Merge branch 'openmethods-merged-dtmf-20110126' of git://scm.dashjr.org/var/scmroot/git/freeswitch
This commit is contained in:
commit
1623e5d295
|
@ -24,6 +24,7 @@
|
|||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
*
|
||||
* switch_core.h -- Core Library
|
||||
|
@ -1734,6 +1735,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s
|
|||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags);
|
||||
|
||||
/*!
|
||||
\brief Feed DTMF to an asr handle
|
||||
\param ah the handle to feed data to
|
||||
\param dtmf a string of DTMF digits
|
||||
\param flags flags to influence behaviour
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
|
||||
|
||||
/*!
|
||||
\brief Check an asr handle for results
|
||||
\param ah the handle to check
|
||||
|
@ -1768,6 +1778,29 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_load_grammar(switch_asr_handle_t
|
|||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Enable a grammar from an asr handle
|
||||
\param ah the handle to enable the grammar from
|
||||
\param name the name of the grammar to enable
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Disable a grammar from an asr handle
|
||||
\param ah the handle to disable the grammar from
|
||||
\param name the name of the grammar to disable
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Disable all grammars from an asr handle
|
||||
\param ah the handle to disable the grammars from
|
||||
\return SWITCH_STATUS_SUCCESS
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah);
|
||||
|
||||
/*!
|
||||
\brief Pause detection on an asr handle
|
||||
\param ah the handle to pause
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Neal Horman <neal at wanlink dot com>
|
||||
* Bret McDanel <trixter AT 0xdecafbad dot com>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
* switch_ivr.h -- IVR Library
|
||||
*
|
||||
|
@ -198,8 +199,38 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_load_grammar(switch_cor
|
|||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Enable a grammar on a background speech detection handle
|
||||
\param session The session to change the grammar on
|
||||
\param name the grammar name
|
||||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Disable a grammar on a background speech detection handle
|
||||
\param session The session to change the grammar on
|
||||
\param name the grammar name
|
||||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name);
|
||||
|
||||
/*!
|
||||
\brief Disable all grammars on a background speech detection handle
|
||||
\param session The session to change the grammar on
|
||||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_session_t *session, const char *name, const char *val);
|
||||
|
||||
/*!
|
||||
\brief Start input timers on a background speech detection handle
|
||||
\param session The session to start the timers on
|
||||
\return SWITCH_STATUS_SUCCESS if all is well
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session);
|
||||
|
||||
/*!
|
||||
\brief Record a session to disk
|
||||
\param session the session to record
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Contributor(s):
|
||||
*
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
*
|
||||
* switch_module_interfaces.h -- Module Interface Definitions
|
||||
|
@ -396,6 +397,14 @@ struct switch_asr_interface {
|
|||
switch_mutex_t *reflock;
|
||||
switch_loadable_module_interface_t *parent;
|
||||
struct switch_asr_interface *next;
|
||||
/*! function to enable a grammar to the asr interface */
|
||||
switch_status_t (*asr_enable_grammar) (switch_asr_handle_t *ah, const char *name);
|
||||
/*! function to disable a grammar to the asr interface */
|
||||
switch_status_t (*asr_disable_grammar) (switch_asr_handle_t *ah, const char *name);
|
||||
/*! function to disable all grammars to the asr interface */
|
||||
switch_status_t (*asr_disable_all_grammars) (switch_asr_handle_t *ah);
|
||||
/*! function to feed DTMF to the ASR */
|
||||
switch_status_t (*asr_feed_dtmf) (switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
|
||||
};
|
||||
|
||||
/*! an abstract representation of an asr speech interface. */
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* Michael Murdock <mike at mmurdock dot org>
|
||||
* Neal Horman <neal at wanlink dot com>
|
||||
* Bret McDanel <trixter AT 0xdecafbad dot com>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
* mod_dptools.c -- Raw Audio File Streaming Application Module
|
||||
*
|
||||
|
@ -269,7 +270,7 @@ SWITCH_STANDARD_APP(bind_digit_action_function)
|
|||
}
|
||||
|
||||
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR pause OR resume OR stop OR param <name> <value>"
|
||||
#define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron/grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR start_input_timers OR stop OR param <name> <value>"
|
||||
SWITCH_STANDARD_APP(detect_speech_function)
|
||||
{
|
||||
char *argv[4];
|
||||
|
@ -282,6 +283,12 @@ SWITCH_STANDARD_APP(detect_speech_function)
|
|||
switch_ivr_detect_speech_load_grammar(session, argv[1], argv[2]);
|
||||
} else if (!strcasecmp(argv[0], "nogrammar")) {
|
||||
switch_ivr_detect_speech_unload_grammar(session, argv[1]);
|
||||
} else if (!strcasecmp(argv[0], "grammaron")) {
|
||||
switch_ivr_detect_speech_enable_grammar(session, argv[1]);
|
||||
} else if (!strcasecmp(argv[0], "grammaroff")) {
|
||||
switch_ivr_detect_speech_disable_grammar(session, argv[1]);
|
||||
} else if (!strcasecmp(argv[0], "grammarsalloff")) {
|
||||
switch_ivr_detect_speech_disable_all_grammars(session);
|
||||
} else if (!strcasecmp(argv[0], "pause")) {
|
||||
switch_ivr_pause_detect_speech(session);
|
||||
} else if (!strcasecmp(argv[0], "resume")) {
|
||||
|
@ -290,6 +297,8 @@ SWITCH_STANDARD_APP(detect_speech_function)
|
|||
switch_ivr_stop_detect_speech(session);
|
||||
} else if (!strcasecmp(argv[0], "param")) {
|
||||
switch_ivr_set_param_detect_speech(session, argv[1], argv[2]);
|
||||
} else if (!strcasecmp(argv[0], "start_input_timers")) {
|
||||
switch_ivr_detect_speech_start_input_timers(session);
|
||||
} else if (argc >= 3) {
|
||||
switch_ivr_detect_speech(session, argv[0], argv[1], argv[2], argv[3], NULL);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*
|
||||
* Brian West <brian@freeswitch.org>
|
||||
* Christopher M. Rienzo <chris@rienzo.net>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
* mod_unimrcp.c -- UniMRCP module (MRCP client)
|
||||
*
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include "mrcp_resource_loader.h"
|
||||
#include "mpf_engine.h"
|
||||
#include "mpf_codec_manager.h"
|
||||
#include "mpf_dtmf_generator.h"
|
||||
#include "mpf_rtp_termination_factory.h"
|
||||
#include "mrcp_sofiasip_client_agent.h"
|
||||
#include "mrcp_unirtsp_client_agent.h"
|
||||
|
@ -433,14 +435,20 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile)
|
|||
struct recognizer_data {
|
||||
/** the available grammars */
|
||||
switch_hash_t *grammars;
|
||||
/** the last grammar used (for pause/resume) */
|
||||
grammar_t *last_grammar;
|
||||
/** the enabled grammars */
|
||||
switch_hash_t *enabled_grammars;
|
||||
/** recognize result */
|
||||
char *result;
|
||||
/** true, if voice has started */
|
||||
int start_of_input;
|
||||
/** true, if input timers have started */
|
||||
int timers_started;
|
||||
/** UniMRCP mpf stream */
|
||||
mpf_audio_stream_t *unimrcp_stream;
|
||||
/** DTMF generator */
|
||||
mpf_dtmf_generator_t *dtmf_generator;
|
||||
/** true, if presently transmitting DTMF */
|
||||
char dtmf_generator_active;
|
||||
};
|
||||
typedef struct recognizer_data recognizer_data_t;
|
||||
|
||||
|
@ -451,8 +459,12 @@ static switch_status_t recog_shutdown();
|
|||
static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name);
|
||||
static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name);
|
||||
static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah);
|
||||
static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags);
|
||||
static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags);
|
||||
#if 0
|
||||
static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name);
|
||||
#endif
|
||||
|
@ -468,12 +480,16 @@ static void recog_asr_float_param(switch_asr_handle_t *ah, char *param, double v
|
|||
/* recognizer's interface for UniMRCP */
|
||||
static apt_bool_t recog_message_handler(const mrcp_app_message_t *app_message);
|
||||
static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp_session_t *session, mrcp_channel_t *channel, mrcp_message_t *message);
|
||||
static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec);
|
||||
static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame);
|
||||
|
||||
/* recognizer specific speech_channel_funcs */
|
||||
static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name);
|
||||
static switch_status_t recog_channel_start(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_load_grammar(speech_channel_t *schannel, const char *name, grammar_type_t type, const char *data);
|
||||
static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel, const char *name);
|
||||
static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *name);
|
||||
static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *name);
|
||||
static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_check_results(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_set_start_of_input(speech_channel_t *schannel);
|
||||
static switch_status_t recog_channel_start_input_timers(speech_channel_t *schannel);
|
||||
|
@ -2055,19 +2071,24 @@ static const char *grammar_type_to_mime(grammar_type_t type, profile_t *profile)
|
|||
* Start RECOGNIZE request
|
||||
*
|
||||
* @param schannel the channel to start
|
||||
* @param name the name of the grammar to use or NULL if to reuse the last grammar
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_channel_start(speech_channel_t *schannel, const char *name)
|
||||
static switch_status_t recog_channel_start(speech_channel_t *schannel)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_hash_index_t *egk;
|
||||
mrcp_message_t *mrcp_message;
|
||||
mrcp_recog_header_t *recog_header;
|
||||
mrcp_generic_header_t *generic_header;
|
||||
recognizer_data_t *r;
|
||||
char *start_input_timers;
|
||||
const char *mime_type;
|
||||
grammar_t *grammar = NULL;
|
||||
char *key;
|
||||
switch_size_t len;
|
||||
grammar_t *grammar;
|
||||
switch_size_t grammar_uri_count = 0;
|
||||
switch_size_t grammar_uri_list_len = 0;
|
||||
char *grammar_uri_list = NULL;
|
||||
|
||||
switch_mutex_lock(schannel->mutex);
|
||||
if (schannel->state != SPEECH_CHANNEL_READY) {
|
||||
|
@ -2088,22 +2109,56 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
|
|||
start_input_timers = (char *) switch_core_hash_find(schannel->params, "start-input-timers");
|
||||
r->timers_started = zstr(start_input_timers) || strcasecmp(start_input_timers, "false");
|
||||
|
||||
/* get the cached grammar */
|
||||
if (zstr(name)) {
|
||||
grammar = r->last_grammar;
|
||||
} else {
|
||||
grammar = (grammar_t *) switch_core_hash_find(r->grammars, name);
|
||||
r->last_grammar = grammar;
|
||||
}
|
||||
if (grammar == NULL) {
|
||||
if (name) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, name);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name);
|
||||
}
|
||||
/* count enabled grammars */
|
||||
for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) {
|
||||
// NOTE: This postponed type check is necessary to allow a non-URI-list grammar to execute alone
|
||||
if (grammar_uri_count == 1 && grammar->type != GRAMMAR_TYPE_URI)
|
||||
goto no_grammar_alone;
|
||||
++grammar_uri_count;
|
||||
switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
|
||||
if (grammar->type != GRAMMAR_TYPE_URI && grammar_uri_count != 1) {
|
||||
no_grammar_alone:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Grammar '%s' can only be used alone (not a URI list)\n", schannel->name, key);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
len = strlen(grammar->data);
|
||||
if (!len)
|
||||
continue;
|
||||
grammar_uri_list_len += len;
|
||||
if (grammar->data[len - 1] != '\n')
|
||||
grammar_uri_list_len += 2;
|
||||
}
|
||||
|
||||
switch (grammar_uri_count) {
|
||||
case 0:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) No grammar specified\n", schannel->name);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
case 1:
|
||||
/* grammar should already be the unique grammar */
|
||||
break;
|
||||
default:
|
||||
/* get the enabled grammars list */
|
||||
grammar_uri_list = switch_core_alloc(schannel->memory_pool, grammar_uri_list_len + 1);
|
||||
grammar_uri_list_len = 0;
|
||||
for (egk = switch_hash_first(NULL, r->enabled_grammars); egk; egk = switch_hash_next(egk)) {
|
||||
switch_hash_this(egk, (void *) &key, NULL, (void *) &grammar);
|
||||
len = strlen(grammar->data);
|
||||
if (!len)
|
||||
continue;
|
||||
memcpy(&(grammar_uri_list[grammar_uri_list_len]), grammar->data, len);
|
||||
grammar_uri_list_len += len;
|
||||
if (grammar_uri_list[grammar_uri_list_len - 1] != '\n')
|
||||
{
|
||||
grammar_uri_list_len += 2;
|
||||
grammar_uri_list[grammar_uri_list_len - 2] = '\r';
|
||||
grammar_uri_list[grammar_uri_list_len - 1] = '\n';
|
||||
}
|
||||
}
|
||||
grammar_uri_list[grammar_uri_list_len++] = '\0';
|
||||
grammar = NULL;
|
||||
}
|
||||
|
||||
/* create MRCP message */
|
||||
mrcp_message = mrcp_application_message_create(schannel->unimrcp_session, schannel->unimrcp_channel, RECOGNIZER_RECOGNIZE);
|
||||
|
@ -2120,7 +2175,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
|
|||
}
|
||||
|
||||
/* set Content-Type */
|
||||
mime_type = grammar_type_to_mime(grammar->type, schannel->profile);
|
||||
mime_type = grammar_type_to_mime(grammar ? grammar->type : GRAMMAR_TYPE_URI, schannel->profile);
|
||||
if (zstr(mime_type)) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
|
@ -2129,7 +2184,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
|
|||
mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_TYPE);
|
||||
|
||||
/* set Content-ID for inline grammars */
|
||||
if (grammar->type != GRAMMAR_TYPE_URI) {
|
||||
if (grammar && grammar->type != GRAMMAR_TYPE_URI) {
|
||||
apt_string_assign(&generic_header->content_id, grammar->name, mrcp_message->pool);
|
||||
mrcp_generic_header_property_add(mrcp_message, GENERIC_HEADER_CONTENT_ID);
|
||||
}
|
||||
|
@ -2151,7 +2206,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha
|
|||
recog_channel_set_params(schannel, mrcp_message, generic_header, recog_header);
|
||||
|
||||
/* set message body */
|
||||
apt_string_assign(&mrcp_message->body, grammar->data, mrcp_message->pool);
|
||||
apt_string_assign(&mrcp_message->body, grammar ? grammar->data : grammar_uri_list, mrcp_message->pool);
|
||||
|
||||
/* Empty audio queue and send RECOGNIZE to MRCP server */
|
||||
audio_queue_clear(schannel->audio_queue);
|
||||
|
@ -2286,12 +2341,84 @@ static switch_status_t recog_channel_unload_grammar(speech_channel_t *schannel,
|
|||
} else {
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Unloading grammar %s\n", schannel->name, grammar_name);
|
||||
switch_core_hash_delete(r->enabled_grammars, grammar_name);
|
||||
switch_core_hash_delete(r->grammars, grammar_name);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable speech recognition grammar
|
||||
*
|
||||
* @param schannel the recognizer channel
|
||||
* @param grammar_name the name of the grammar to enable
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_channel_enable_grammar(speech_channel_t *schannel, const char *grammar_name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
if (zstr(grammar_name)) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
} else {
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
grammar_t *grammar;
|
||||
grammar = (grammar_t *) switch_core_hash_find(r->grammars, grammar_name);
|
||||
if (grammar == NULL)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Undefined grammar, %s\n", schannel->name, grammar_name);
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Enabling grammar %s\n", schannel->name, grammar_name);
|
||||
switch_core_hash_insert(r->enabled_grammars, grammar_name, grammar);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable speech recognition grammar
|
||||
*
|
||||
* @param schannel the recognizer channel
|
||||
* @param grammar_name the name of the grammar to disable
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_channel_disable_grammar(speech_channel_t *schannel, const char *grammar_name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
if (zstr(grammar_name)) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
} else {
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling grammar %s\n", schannel->name, grammar_name);
|
||||
switch_core_hash_delete(r->enabled_grammars, grammar_name);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all speech recognition grammars
|
||||
*
|
||||
* @param schannel the recognizer channel
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_channel_disable_all_grammars(speech_channel_t *schannel)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Disabling all grammars\n", schannel->name);
|
||||
switch_core_hash_destroy(&r->enabled_grammars);
|
||||
switch_core_hash_init(&r->enabled_grammars, schannel->memory_pool);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if recognition is complete
|
||||
*
|
||||
|
@ -2451,6 +2578,8 @@ static switch_status_t recog_channel_set_params(speech_channel_t *schannel, mrcp
|
|||
if (id) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) \"%s\": \"%s\"\n", schannel->name, param_name, param_val);
|
||||
recog_channel_set_header(schannel, id->id, param_val, msg, recog_hdr);
|
||||
} else if (!strcasecmp(param_name, "start-recognize")) {
|
||||
// This parameter is used internally only, not in MRCP headers
|
||||
} else {
|
||||
/* this is probably a vendor-specific MRCP param */
|
||||
apt_str_t apt_param_name = { 0 };
|
||||
|
@ -2737,6 +2866,7 @@ static switch_status_t recog_asr_open(switch_asr_handle_t *ah, const char *codec
|
|||
schannel->data = r;
|
||||
memset(r, 0, sizeof(recognizer_data_t));
|
||||
switch_core_hash_init(&r->grammars, ah->memory_pool);
|
||||
switch_core_hash_init(&r->enabled_grammars, ah->memory_pool);
|
||||
|
||||
/* Open the channel */
|
||||
if (zstr(profile_name)) {
|
||||
|
@ -2782,6 +2912,7 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha
|
|||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
const char *grammar_data = NULL;
|
||||
char *grammar_file_data = NULL;
|
||||
char *start_recognize;
|
||||
switch_file_t *grammar_file = NULL;
|
||||
switch_size_t grammar_file_size = 0, to_read = 0;
|
||||
grammar_type_t type = GRAMMAR_TYPE_UNKNOWN;
|
||||
|
@ -2886,7 +3017,19 @@ static switch_status_t recog_asr_load_grammar(switch_asr_handle_t *ah, const cha
|
|||
goto done;
|
||||
}
|
||||
|
||||
status = recog_channel_start(schannel, name);
|
||||
start_recognize = (char *) switch_core_hash_find(schannel->params, "start-recognize");
|
||||
if (zstr(start_recognize) || strcasecmp(start_recognize, "false"))
|
||||
{
|
||||
if (recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
if (recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto done;
|
||||
}
|
||||
status = recog_channel_start(schannel);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
|
@ -2914,6 +3057,57 @@ static switch_status_t recog_asr_unload_grammar(switch_asr_handle_t *ah, const c
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_enable_grammar request from FreeSWITCH.
|
||||
*
|
||||
* FreeSWITCH sends this request to enable recognition on this grammar.
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @param name the grammar name.
|
||||
*/
|
||||
static switch_status_t recog_asr_enable_grammar(switch_asr_handle_t *ah, const char *name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_enable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_disable_grammar request from FreeSWITCH.
|
||||
*
|
||||
* FreeSWITCH sends this request to disable recognition on this grammar.
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @param name the grammar name.
|
||||
*/
|
||||
static switch_status_t recog_asr_disable_grammar(switch_asr_handle_t *ah, const char *name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
if (zstr(name) || speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_grammar(schannel, name) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_disable_all_grammars request from FreeSWITCH.
|
||||
*
|
||||
* FreeSWITCH sends this request to disable recognition of all grammars.
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @param name the grammar name.
|
||||
*/
|
||||
static switch_status_t recog_asr_disable_all_grammars(switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
if (speech_channel_stop(schannel) != SWITCH_STATUS_SUCCESS || recog_channel_disable_all_grammars(schannel) != SWITCH_STATUS_SUCCESS) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_close request from FreeSWITCH
|
||||
*
|
||||
|
@ -2928,6 +3122,10 @@ static switch_status_t recog_asr_close(switch_asr_handle_t *ah, switch_asr_flag_
|
|||
speech_channel_stop(schannel);
|
||||
speech_channel_destroy(schannel);
|
||||
switch_core_hash_destroy(&r->grammars);
|
||||
switch_core_hash_destroy(&r->enabled_grammars);
|
||||
if (r->dtmf_generator) {
|
||||
mpf_dtmf_generator_destroy(r->dtmf_generator);
|
||||
}
|
||||
|
||||
/* this lets FreeSWITCH's speech_thread know the handle is closed */
|
||||
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
|
||||
|
@ -2948,18 +3146,50 @@ static switch_status_t recog_asr_feed(switch_asr_handle_t *ah, void *data, unsig
|
|||
return speech_channel_write(schannel, data, &slen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process asr_feed_dtmf request from FreeSWITCH
|
||||
*
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags)
|
||||
{
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
char digits[2];
|
||||
|
||||
if (!r->dtmf_generator) {
|
||||
if (!r->unimrcp_stream) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: No UniMRCP stream object open\n", schannel->name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
r->dtmf_generator = mpf_dtmf_generator_create(r->unimrcp_stream, schannel->unimrcp_session->pool);
|
||||
if (!r->dtmf_generator) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Cannot queue DTMF: Failed to create DTMF generator\n", schannel->name);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
digits[0] = dtmf->digit;
|
||||
digits[1] = '\0';
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Queued DTMF: %s\n", schannel->name, digits);
|
||||
mpf_dtmf_generator_enqueue(r->dtmf_generator, digits);
|
||||
r->dtmf_generator_active = 1;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Process asr_start request from FreeSWITCH
|
||||
* @param ah the FreeSWITCH speech recognition handle
|
||||
* @param name name of the grammar to use
|
||||
* @return SWITCH_STATUS_SUCCESS if successful
|
||||
*/
|
||||
static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name)
|
||||
static switch_status_t recog_asr_start(switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_status_t status;
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
status = recog_channel_start(schannel, name);
|
||||
status = recog_channel_start(schannel);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
@ -2972,7 +3202,7 @@ static switch_status_t recog_asr_start(switch_asr_handle_t *ah, const char *name
|
|||
static switch_status_t recog_asr_resume(switch_asr_handle_t *ah)
|
||||
{
|
||||
speech_channel_t *schannel = (speech_channel_t *) ah->private_info;
|
||||
return recog_channel_start(schannel, NULL);
|
||||
return recog_channel_start(schannel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3194,6 +3424,23 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* UniMRCP callback requesting open for speech recognition
|
||||
*
|
||||
* @param stream the UniMRCP stream
|
||||
* @param codec the codec
|
||||
* @return TRUE
|
||||
*/
|
||||
static apt_bool_t recog_stream_open(mpf_audio_stream_t *stream, mpf_codec_t *codec)
|
||||
{
|
||||
speech_channel_t *schannel = (speech_channel_t *) stream->obj;
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
|
||||
r->unimrcp_stream = stream;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* UniMRCP callback requesting next frame for speech recognition
|
||||
*
|
||||
|
@ -3204,6 +3451,7 @@ static apt_bool_t recog_on_message_receive(mrcp_application_t *application, mrcp
|
|||
static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *frame)
|
||||
{
|
||||
speech_channel_t *schannel = (speech_channel_t *) stream->obj;
|
||||
recognizer_data_t *r = (recognizer_data_t *) schannel->data;
|
||||
switch_size_t to_read = frame->codec_frame.size;
|
||||
|
||||
/* grab the data. pad it if there isn't enough */
|
||||
|
@ -3214,6 +3462,13 @@ static apt_bool_t recog_stream_read(mpf_audio_stream_t *stream, mpf_frame_t *fra
|
|||
frame->type |= MEDIA_FRAME_TYPE_AUDIO;
|
||||
}
|
||||
|
||||
if (r->dtmf_generator_active) {
|
||||
if (!mpf_dtmf_generator_put_frame(r->dtmf_generator, frame)) {
|
||||
if (!mpf_dtmf_generator_sending(r->dtmf_generator))
|
||||
r->dtmf_generator_active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3231,8 +3486,12 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
|
|||
asr_interface->asr_open = recog_asr_open;
|
||||
asr_interface->asr_load_grammar = recog_asr_load_grammar;
|
||||
asr_interface->asr_unload_grammar = recog_asr_unload_grammar;
|
||||
asr_interface->asr_enable_grammar = recog_asr_enable_grammar;
|
||||
asr_interface->asr_disable_grammar = recog_asr_disable_grammar;
|
||||
asr_interface->asr_disable_all_grammars = recog_asr_disable_all_grammars;
|
||||
asr_interface->asr_close = recog_asr_close;
|
||||
asr_interface->asr_feed = recog_asr_feed;
|
||||
asr_interface->asr_feed_dtmf = recog_asr_feed_dtmf;
|
||||
#if 0
|
||||
asr_interface->asr_start = recog_asr_start;
|
||||
#endif
|
||||
|
@ -3255,7 +3514,7 @@ static switch_status_t recog_load(switch_loadable_module_interface_t *module_int
|
|||
globals.recog.dispatcher.on_channel_remove = speech_on_channel_remove;
|
||||
globals.recog.dispatcher.on_message_receive = recog_on_message_receive;
|
||||
globals.recog.audio_stream_vtable.destroy = NULL;
|
||||
globals.recog.audio_stream_vtable.open_rx = NULL;
|
||||
globals.recog.audio_stream_vtable.open_rx = recog_stream_open;
|
||||
globals.recog.audio_stream_vtable.close_rx = NULL;
|
||||
globals.recog.audio_stream_vtable.read_frame = recog_stream_read;
|
||||
globals.recog.audio_stream_vtable.open_tx = NULL;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* Michael Jerris <mike@jerris.com>
|
||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
||||
* Christopher M. Rienzo <chris@rienzo.net>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
*
|
||||
* switch_core_asr.c -- Main Core Library (Speech Detection Interface)
|
||||
|
@ -160,6 +161,45 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_unload_grammar(switch_asr_handle
|
|||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
switch_assert(ah != NULL);
|
||||
|
||||
if (ah->asr_interface->asr_enable_grammar) {
|
||||
status = ah->asr_interface->asr_enable_grammar(ah, name);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
switch_assert(ah != NULL);
|
||||
|
||||
if (ah->asr_interface->asr_disable_grammar) {
|
||||
status = ah->asr_interface->asr_disable_grammar(ah, name);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
switch_assert(ah != NULL);
|
||||
|
||||
if (ah->asr_interface->asr_disable_all_grammars) {
|
||||
status = ah->asr_interface->asr_disable_all_grammars(ah);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_pause(switch_asr_handle_t *ah)
|
||||
{
|
||||
switch_assert(ah != NULL);
|
||||
|
@ -199,6 +239,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_feed(switch_asr_handle_t *ah, vo
|
|||
return ah->asr_interface->asr_feed(ah, data, len, flags);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
switch_assert(ah != NULL);
|
||||
|
||||
if (ah->asr_interface->asr_feed_dtmf) {
|
||||
status = ah->asr_interface->asr_feed_dtmf(ah, dtmf, flags);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
|
||||
{
|
||||
switch_assert(ah != NULL);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Michael Jerris <mike@jerris.com>
|
||||
* Bret McDanel <bret AT 0xdecafbad dot com>
|
||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||
*
|
||||
* switch_ivr_async.c -- IVR Library (async operations)
|
||||
*
|
||||
|
@ -3208,6 +3209,20 @@ static switch_bool_t speech_callback(switch_media_bug_t *bug, void *user_data, s
|
|||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
static switch_status_t speech_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
|
||||
|
||||
if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_stop_detect_speech(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
@ -3277,6 +3292,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_set_param_detect_speech(switch_core_s
|
|||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
|
||||
if (sth) {
|
||||
switch_core_asr_start_input_timers(sth->ah);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_core_session_t *session, const char *name)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
@ -3294,6 +3321,57 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_unload_grammar(switch_c
|
|||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_enable_grammar(switch_core_session_t *session, const char *name)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
switch_status_t status;
|
||||
|
||||
if (sth) {
|
||||
if ((status = switch_core_asr_enable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error enabling Grammar\n");
|
||||
switch_core_asr_close(sth->ah, &flags);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_grammar(switch_core_session_t *session, const char *name)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
switch_status_t status;
|
||||
|
||||
if (sth) {
|
||||
if ((status = switch_core_asr_disable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling Grammar\n");
|
||||
switch_core_asr_close(sth->ah, &flags);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_disable_all_grammars(switch_core_session_t *session)
|
||||
{
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
|
||||
struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
|
||||
switch_status_t status;
|
||||
|
||||
if (sth) {
|
||||
if ((status = switch_core_asr_disable_all_grammars(sth->ah)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling all Grammars\n");
|
||||
switch_core_asr_close(sth->ah, &flags);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *session,
|
||||
const char *mod_name,
|
||||
const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
|
||||
|
@ -3360,6 +3438,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech(switch_core_session_t *
|
|||
return status;
|
||||
}
|
||||
|
||||
if ((status = switch_core_event_hook_add_recv_dtmf(session, speech_on_dtmf)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_ivr_stop_detect_speech(session);
|
||||
return status;
|
||||
}
|
||||
|
||||
switch_channel_set_private(channel, SWITCH_SPEECH_KEY, sth);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
|
Loading…
Reference in New Issue