mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 17:38:59 +00:00
commit e8f60761378fe392d80e89d0e3481316119e9809
Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Tue Jun 30 14:44:09 2009 +0000 Further build and install integration git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1030 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 5b410e0dfc1852ee5c0d56d64b326d5130aed18a Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Tue Jun 30 13:24:27 2009 +0000 Added utility project (preparesphinx) to copy the stuff pocketsphinx requires to run git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1029 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 2457575de160b378affdfa7a37cac1282d0024ca Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Tue Jun 30 13:18:59 2009 +0000 Added a few more comments in config file git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1028 f001bc3a-424a-0410-80a0-a715b8f413a8 commit ffc40b15b409a79bdea286898ad1e8694fc1623c Author: garmt.noname@gmail.com <garmt.noname@gmail.com@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Tue Jun 30 10:38:54 2009 +0000 Added resampling to 8kHz so that it works with freeswitch (specify only L16/96/8000 codec in profile of media_engine/rtpfactory). Changed logging to DEBUG level rather than INFO. Added channel_guard for stop response. git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1027 f001bc3a-424a-0410-80a0-a715b8f413a8 commit d11439611186b46f1bfabc036b7e5d76f33f8b0e Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 19:46:54 2009 +0000 Added entries for PocketSphinx (mrcppocketsphinx) and Flite (mrcpflite) plugins into unimrcpserver.xml (disabled by default) git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1026 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 63bc73426ba4efdf648a28cd3c1ff1daaef5bb49 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 15:04:01 2009 +0000 Added enumeration of pocketsphinx models (narrowband, wideband), supported wideband either git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1025 f001bc3a-424a-0410-80a0-a715b8f413a8 commit d11439611186b46f1bfabc036b7e5d76f33f8b0e Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 19:46:54 2009 +0000 Added entries for PocketSphinx (mrcppocketsphinx) and Flite (mrcpflite) plugins into unimrcpserver.xml (disabled by default) git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1026 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 63bc73426ba4efdf648a28cd3c1ff1daaef5bb49 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 15:04:01 2009 +0000 Added enumeration of pocketsphinx models (narrowband, wideband), supported wideband either git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1025 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 04970484e4357e2a1c3c4385840640caada33468 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 13:21:35 2009 +0000 Removed engine->guard, as all relevant calls are made within the context of the same thread git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1024 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 9bac2f3abdcfea5397aca4b86e209af090631e7a Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jun 29 13:15:30 2009 +0000 Initialized 16kHz codec descriptor for flite channel, since available flite voice are in 16kHz. git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1023 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 4e902eb985b433416723f15646d3e99d385d18cb Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sun Jun 28 20:05:22 2009 +0000 Do not create bridge if resampling is required. Several sampling rates are supported, but there is no resampling yet. git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1022 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 6d35b1246a7061e4c8f3f608bb17e146870d63bd Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sun Jun 28 18:14:25 2009 +0000 Added makefile target to install pocketsphinx.xml with make install git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1021 f001bc3a-424a-0410-80a0-a715b8f413a8 commit c2b75c89d57c02bd8d4360aebcb7406ecbf90eb0 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sun Jun 28 18:10:01 2009 +0000 Set svn props (eol:native) git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1020 f001bc3a-424a-0410-80a0-a715b8f413a8 commit dd91ebea823dd2169e8c30f0cfe87fa199e1a0c2 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sun Jun 28 17:46:46 2009 +0000 Loaded pocketsphinx's properties from config file git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1019 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 2ba91890593d7a64136e675bb937efd9a2542cc7 Author: garmt.noname@gmail.com <garmt.noname@gmail.com@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sun Jun 28 12:29:54 2009 +0000 Removed session tasks, most channel tasks, flite voices are no longer global git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1018 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 0d739127f9267b3ad871d1a53a863802f101a6b5 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jun 27 09:15:20 2009 +0000 Implemented save_waveform, utterance will be saved in the filesystem git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1017 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 4ffd282ddf54ad861d73f36567ad201d135feff5 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jun 27 08:24:19 2009 +0000 Set 2 digits precision (digits after the decimal point) while generating float type values (Issue-35). git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1016 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 90446f5e6ece40e91fd5b340a45e6773e4e80a0f Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jun 27 07:42:52 2009 +0000 Set noinut and recognition timeouts if specified in RECOGNIZE request, reset input timer on partial match git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1015 f001bc3a-424a-0410-80a0-a715b8f413a8 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14104 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
@@ -35,14 +35,15 @@
|
||||
#include "mrcp_generic_header.h"
|
||||
#include "mrcp_message.h"
|
||||
#include "mpf_activity_detector.h"
|
||||
#include "pocketsphinx_properties.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
#define POCKETSPHINX_CONFFILE_NAME "pocketsphinx.xml"
|
||||
|
||||
#define RECOGNIZER_SIDRES(recognizer) (recognizer)->channel->id.buf, "pocketsphinx"
|
||||
|
||||
typedef struct pocketsphinx_engine_t pocketsphinx_engine_t;
|
||||
typedef struct pocketsphinx_recognizer_t pocketsphinx_recognizer_t;
|
||||
typedef struct pocketsphinx_properties_t pocketsphinx_properties_t;
|
||||
|
||||
/** Methods of recognition engine */
|
||||
static apt_bool_t pocketsphinx_engine_destroy(mrcp_resource_engine_t *engine);
|
||||
@@ -86,23 +87,14 @@ static const mpf_audio_stream_vtable_t audio_stream_vtable = {
|
||||
|
||||
/** Pocketsphinx engine (engine is an aggregation of recognizers) */
|
||||
struct pocketsphinx_engine_t {
|
||||
mrcp_resource_engine_t *base;
|
||||
};
|
||||
|
||||
/** Pocketsphinx properties */
|
||||
struct pocketsphinx_properties_t {
|
||||
const char *dictionary;
|
||||
const char *model_8k;
|
||||
const char *model_16k;
|
||||
apr_size_t noinput_timeout;
|
||||
apr_size_t recognition_timeout;
|
||||
apr_size_t partial_result_timeout;
|
||||
/* Resource engine base */
|
||||
mrcp_resource_engine_t *base;
|
||||
/** Properties loaded from config file */
|
||||
pocketsphinx_properties_t properties;
|
||||
};
|
||||
|
||||
/** Pocketsphinx channel (recognizer) */
|
||||
struct pocketsphinx_recognizer_t {
|
||||
/** Back pointer to engine */
|
||||
pocketsphinx_engine_t *engine;
|
||||
/** Engine channel base */
|
||||
mrcp_engine_channel_t *channel;
|
||||
|
||||
@@ -110,12 +102,12 @@ struct pocketsphinx_recognizer_t {
|
||||
ps_decoder_t *decoder;
|
||||
/** Configuration */
|
||||
cmd_ln_t *config;
|
||||
/** Properties (to be loaded from config file) */
|
||||
/** Recognizer properties coppied from defualt engine properties */
|
||||
pocketsphinx_properties_t properties;
|
||||
/** Is input timer started */
|
||||
apt_bool_t is_input_timer_on;
|
||||
/** Noinput timeout */
|
||||
apr_size_t noinput_timeout;
|
||||
apr_size_t no_input_timeout;
|
||||
/** Recognition timeout */
|
||||
apr_size_t recognition_timeout;
|
||||
/** Timeout elapsed since the last partial result checking */
|
||||
@@ -126,6 +118,8 @@ struct pocketsphinx_recognizer_t {
|
||||
const char *grammar_id;
|
||||
/** Table of defined grammars (key=content-id, value=grammar-file-path) */
|
||||
apr_table_t *grammar_table;
|
||||
/** File to write waveform to if save_waveform is on */
|
||||
apr_file_t *waveform;
|
||||
|
||||
/** Voice activity detector */
|
||||
mpf_activity_detector_t *detector;
|
||||
@@ -170,33 +164,42 @@ MRCP_PLUGIN_DECLARE(mrcp_resource_engine_t*) mrcp_plugin_create(apr_pool_t *pool
|
||||
}
|
||||
|
||||
/** Destroy pocketsphinx engine */
|
||||
static apt_bool_t pocketsphinx_engine_destroy(mrcp_resource_engine_t *engine)
|
||||
static apt_bool_t pocketsphinx_engine_destroy(mrcp_resource_engine_t *resource_engine)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Open pocketsphinx engine */
|
||||
static apt_bool_t pocketsphinx_engine_open(mrcp_resource_engine_t *engine)
|
||||
static apt_bool_t pocketsphinx_engine_open(mrcp_resource_engine_t *resource_engine)
|
||||
{
|
||||
pocketsphinx_engine_t *engine = resource_engine->obj;
|
||||
const apt_dir_layout_t *dir_layout = resource_engine->dir_layout;
|
||||
|
||||
char *file_path = NULL;
|
||||
apr_filepath_merge(&file_path,dir_layout->conf_dir_path,POCKETSPHINX_CONFFILE_NAME,0,resource_engine->pool);
|
||||
|
||||
/* load properties */
|
||||
pocketsphinx_properties_load(&engine->properties,file_path,dir_layout,resource_engine->pool);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Close pocketsphinx engine */
|
||||
static apt_bool_t pocketsphinx_engine_close(mrcp_resource_engine_t *engine)
|
||||
static apt_bool_t pocketsphinx_engine_close(mrcp_resource_engine_t *resource_engine)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Create pocketsphinx recognizer */
|
||||
static mrcp_engine_channel_t* pocketsphinx_engine_recognizer_create(mrcp_resource_engine_t *engine, apr_pool_t *pool)
|
||||
static mrcp_engine_channel_t* pocketsphinx_engine_recognizer_create(mrcp_resource_engine_t *resource_engine, apr_pool_t *pool)
|
||||
{
|
||||
mrcp_engine_channel_t *channel;
|
||||
mpf_codec_descriptor_t *codec_descriptor;
|
||||
pocketsphinx_engine_t *engine = resource_engine->obj;
|
||||
pocketsphinx_recognizer_t *recognizer = apr_palloc(pool,sizeof(pocketsphinx_recognizer_t));
|
||||
// recognizer->engine = engine;
|
||||
recognizer->decoder = NULL;
|
||||
recognizer->config = NULL;
|
||||
recognizer->is_input_timer_on = FALSE;
|
||||
recognizer->noinput_timeout = 0;
|
||||
recognizer->no_input_timeout = 0;
|
||||
recognizer->recognition_timeout = 0;
|
||||
recognizer->partial_result_timeout = 0;
|
||||
recognizer->last_result = NULL;
|
||||
@@ -211,10 +214,24 @@ static mrcp_engine_channel_t* pocketsphinx_engine_recognizer_create(mrcp_resourc
|
||||
recognizer->close_requested = FALSE;
|
||||
recognizer->grammar_id = NULL;
|
||||
recognizer->grammar_table = apr_table_make(pool,1);
|
||||
|
||||
recognizer->waveform = NULL;
|
||||
|
||||
/* copy default properties loaded from config */
|
||||
recognizer->properties = engine->properties;
|
||||
|
||||
codec_descriptor = (mpf_codec_descriptor_t *) apr_palloc(pool,sizeof(mpf_codec_descriptor_t));
|
||||
mpf_codec_descriptor_init(codec_descriptor);
|
||||
codec_descriptor->channel_count = 1;
|
||||
codec_descriptor->payload_type = 96;
|
||||
apt_string_set(&codec_descriptor->name,"LPCM");
|
||||
codec_descriptor->sampling_rate = 8000;
|
||||
if(recognizer->properties.preferred_model == POCKETSPHINX_MODEL_WIDEBAND) {
|
||||
codec_descriptor->sampling_rate = 16000;
|
||||
}
|
||||
|
||||
/* create engine channel base */
|
||||
channel = mrcp_engine_sink_channel_create(
|
||||
engine, /* resource engine */
|
||||
resource_engine, /* resource engine */
|
||||
&channel_vtable, /* virtual methods table of engine channel */
|
||||
&audio_stream_vtable, /* virtual methods table of audio stream */
|
||||
recognizer, /* object to associate */
|
||||
@@ -295,33 +312,23 @@ static apt_bool_t pocketsphinx_recognizer_request_process(mrcp_engine_channel_t
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Load pocketsphinx properties [RECOG] */
|
||||
static apt_bool_t pocketsphinx_properties_load(pocketsphinx_recognizer_t *recognizer)
|
||||
{
|
||||
mrcp_engine_channel_t *channel = recognizer->channel;
|
||||
const apt_dir_layout_t *dir_layout = channel->engine->dir_layout;
|
||||
pocketsphinx_properties_t *properties = &recognizer->properties;
|
||||
|
||||
properties->dictionary = apt_datadir_filepath_get(dir_layout,"pocketsphinx/default.dic",channel->pool);
|
||||
properties->model_8k = apt_datadir_filepath_get(dir_layout,"pocketsphinx/communicator",channel->pool);
|
||||
properties->model_16k = apt_datadir_filepath_get(dir_layout,"pocketsphinx/wsj1",channel->pool);
|
||||
|
||||
properties->noinput_timeout = 5000;
|
||||
properties->recognition_timeout = 15000;
|
||||
properties->partial_result_timeout = 100;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Initialize pocketsphinx decoder [RECOG] */
|
||||
static apt_bool_t pocketsphinx_decoder_init(pocketsphinx_recognizer_t *recognizer, const char *grammar)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Init Config "APT_SIDRES_FMT,RECOGNIZER_SIDRES(recognizer));
|
||||
const char *model = recognizer->properties.model_8k;
|
||||
const char *rate = "8000";
|
||||
if(recognizer->properties.preferred_model == POCKETSPHINX_MODEL_WIDEBAND) {
|
||||
model = recognizer->properties.model_16k;
|
||||
rate = "16000";
|
||||
}
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Init Config rate [%s] dictionary [%s] "APT_SIDRES_FMT,
|
||||
rate,
|
||||
recognizer->properties.dictionary,
|
||||
RECOGNIZER_SIDRES(recognizer));
|
||||
recognizer->config = cmd_ln_init(recognizer->config, ps_args(), FALSE,
|
||||
"-samprate", "8000",
|
||||
"-hmm", recognizer->properties.model_8k,
|
||||
"-samprate", rate,
|
||||
"-hmm", model,
|
||||
"-jsgf", grammar,
|
||||
"-dict", recognizer->properties.dictionary,
|
||||
"-frate", "50",
|
||||
@@ -469,7 +476,7 @@ static apt_bool_t pocketsphinx_define_grammar(pocketsphinx_recognizer_t *recogni
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
grammar_file_name = apr_psprintf(channel->pool,"pocketsphinx/%s-%s.gram",channel->id.buf,content_id);
|
||||
grammar_file_name = apr_psprintf(channel->pool,"%s-%s.gram",channel->id.buf,content_id);
|
||||
grammar_file_path = apt_datadir_filepath_get(dir_layout,grammar_file_name,channel->pool);
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Create Grammar File [%s] "APT_SIDRES_FMT,
|
||||
@@ -519,6 +526,7 @@ static apt_bool_t pocketsphinx_define_grammar(pocketsphinx_recognizer_t *recogni
|
||||
/** Process RECOGNIZE request [RECOG] */
|
||||
static apt_bool_t pocketsphinx_recognize(pocketsphinx_recognizer_t *recognizer, mrcp_message_t *request, mrcp_message_t *response)
|
||||
{
|
||||
mrcp_engine_channel_t *channel = recognizer->channel;
|
||||
mrcp_recog_header_t *request_recog_header;
|
||||
mrcp_recog_header_t *response_recog_header = mrcp_resource_header_prepare(response);
|
||||
if(!response_recog_header) {
|
||||
@@ -541,16 +549,43 @@ static apt_bool_t pocketsphinx_recognize(pocketsphinx_recognizer_t *recognizer,
|
||||
if(mrcp_resource_header_property_check(request,RECOGNIZER_HEADER_START_INPUT_TIMERS) == TRUE) {
|
||||
recognizer->is_input_timer_on = request_recog_header->start_input_timers;
|
||||
}
|
||||
if(mrcp_resource_header_property_check(request,RECOGNIZER_HEADER_NO_INPUT_TIMEOUT) == TRUE) {
|
||||
recognizer->properties.no_input_timeout = request_recog_header->no_input_timeout;
|
||||
}
|
||||
if(mrcp_resource_header_property_check(request,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT) == TRUE) {
|
||||
recognizer->properties.recognition_timeout = request_recog_header->recognition_timeout;
|
||||
}
|
||||
if(mrcp_resource_header_property_check(request,RECOGNIZER_HEADER_SAVE_WAVEFORM) == TRUE) {
|
||||
recognizer->properties.save_waveform = request_recog_header->save_waveform;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if waveform (utterance) should be saved */
|
||||
if(recognizer->properties.save_waveform == TRUE) {
|
||||
apr_status_t rv;
|
||||
const char *waveform_file_name = apr_psprintf(channel->pool,"utter-%s-%d.pcm",
|
||||
channel->id.buf,request->start_line.request_id);
|
||||
char *waveform_file_path = NULL;
|
||||
apr_filepath_merge(&waveform_file_path,recognizer->properties.save_waveform_dir,
|
||||
waveform_file_name,0,channel->pool);
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Open Waveform File [%s] "APT_SIDRES_FMT,
|
||||
waveform_file_path,RECOGNIZER_SIDRES(recognizer));
|
||||
rv = apr_file_open(&recognizer->waveform,waveform_file_path,APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY,
|
||||
APR_OS_DEFAULT,channel->pool);
|
||||
if(rv != APR_SUCCESS) {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Cannot Open Waveform File to Write [%s] "APT_SIDRES_FMT,
|
||||
waveform_file_path,RECOGNIZER_SIDRES(recognizer));
|
||||
}
|
||||
}
|
||||
|
||||
response->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS;
|
||||
/* send asynchronous response */
|
||||
mrcp_engine_channel_message_send(recognizer->channel,response);
|
||||
|
||||
mrcp_engine_channel_message_send(channel,response);
|
||||
|
||||
/* reset */
|
||||
mpf_activity_detector_reset(recognizer->detector);
|
||||
recognizer->noinput_timeout = 0;
|
||||
recognizer->no_input_timeout = 0;
|
||||
recognizer->recognition_timeout = 0;
|
||||
recognizer->partial_result_timeout = 0;
|
||||
recognizer->last_result = NULL;
|
||||
@@ -560,7 +595,7 @@ static apt_bool_t pocketsphinx_recognize(pocketsphinx_recognizer_t *recognizer,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Process GET-RESULTS request [RECOG] */
|
||||
/** Process GET-RESULT request [RECOG] */
|
||||
static apt_bool_t pocketsphinx_get_result(pocketsphinx_recognizer_t *recognizer, mrcp_message_t *request, mrcp_message_t *response)
|
||||
{
|
||||
if(pocketsphinx_result_build(recognizer,response) != TRUE) {
|
||||
@@ -609,6 +644,11 @@ static apt_bool_t pocketsphinx_recognition_complete(pocketsphinx_recognizer_t *r
|
||||
recognizer->inprogress_recog = NULL;
|
||||
ps_end_utt(recognizer->decoder);
|
||||
|
||||
if(recognizer->waveform) {
|
||||
apr_file_close(recognizer->waveform);
|
||||
recognizer->waveform = NULL;
|
||||
}
|
||||
|
||||
if(recognizer->stop_response) {
|
||||
/* recognition has been stopped, send STOP response instead */
|
||||
mrcp_message_t *response = recognizer->stop_response;
|
||||
@@ -690,13 +730,10 @@ static apt_bool_t pocketsphinx_request_dispatch(pocketsphinx_recognizer_t *recog
|
||||
static void* APR_THREAD_FUNC pocketsphinx_recognizer_run(apr_thread_t *thread, void *data)
|
||||
{
|
||||
pocketsphinx_recognizer_t *recognizer = data;
|
||||
apt_bool_t status;
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Run Recognition Thread "APT_SIDRES_FMT, RECOGNIZER_SIDRES(recognizer));
|
||||
status = pocketsphinx_properties_load(recognizer);
|
||||
|
||||
/** Send response to channel_open request */
|
||||
mrcp_engine_channel_open_respond(recognizer->channel,status);
|
||||
mrcp_engine_channel_open_respond(recognizer->channel,TRUE);
|
||||
|
||||
do {
|
||||
/** Wait for MRCP requests */
|
||||
@@ -760,7 +797,7 @@ static apt_bool_t pocketsphinx_start_of_input(pocketsphinx_recognizer_t *recogni
|
||||
|
||||
/* set request state */
|
||||
message->start_line.request_state = MRCP_REQUEST_STATE_INPROGRESS;
|
||||
/* send asynch event */
|
||||
/* send asynchronous event */
|
||||
return mrcp_engine_channel_message_send(recognizer->channel,message);
|
||||
}
|
||||
|
||||
@@ -811,6 +848,12 @@ static apt_bool_t pocketsphinx_stream_write(mpf_audio_stream_t *stream, const mp
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if(recognizer->waveform) {
|
||||
/* write utterance to file */
|
||||
apr_size_t size = frame->codec_frame.size;
|
||||
apr_file_write(recognizer->waveform,frame->codec_frame.buffer,&size);
|
||||
}
|
||||
|
||||
if(ps_process_raw(
|
||||
recognizer->decoder,
|
||||
(const int16 *)frame->codec_frame.buffer,
|
||||
@@ -835,13 +878,18 @@ static apt_bool_t pocketsphinx_stream_write(mpf_audio_stream_t *stream, const mp
|
||||
recognizer->last_result = apr_pstrdup(recognizer->channel->pool,hyp);
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Get Recognition Partial Result [%s] Score [%d] "APT_SIDRES_FMT,
|
||||
hyp,score,RECOGNIZER_SIDRES(recognizer));
|
||||
|
||||
/* reset input timer as we have partial match now */
|
||||
if(score != 0 && recognizer->is_input_timer_on) {
|
||||
recognizer->is_input_timer_on = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(recognizer->is_input_timer_on) {
|
||||
recognizer->noinput_timeout += CODEC_FRAME_TIME_BASE;
|
||||
if(recognizer->noinput_timeout == recognizer->properties.noinput_timeout) {
|
||||
recognizer->no_input_timeout += CODEC_FRAME_TIME_BASE;
|
||||
if(recognizer->no_input_timeout == recognizer->properties.no_input_timeout) {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Noinput Timeout Elapsed "APT_SIDRES_FMT,
|
||||
RECOGNIZER_SIDRES(recognizer));
|
||||
pocketsphinx_end_of_input(recognizer,RECOGNIZER_COMPLETION_CAUSE_NO_INPUT_TIMEOUT);
|
||||
|
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <apr_xml.h>
|
||||
#include "pocketsphinx_properties.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
static const apr_xml_elem* pocketsphinx_document_load(const char *file_path, apr_pool_t *pool)
|
||||
{
|
||||
apr_xml_parser *parser = NULL;
|
||||
apr_xml_doc *doc = NULL;
|
||||
const apr_xml_elem *root;
|
||||
apr_file_t *fd = NULL;
|
||||
apr_status_t rv;
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Open PocketSphinx Config File [%s]",file_path);
|
||||
rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool);
|
||||
if(rv != APR_SUCCESS) {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open PocketSphinx Config File [%s]",file_path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rv = apr_xml_parse_file(pool,&parser,&doc,fd,2000);
|
||||
if(rv != APR_SUCCESS) {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse PocketSphinx Config File [%s]",file_path);
|
||||
apr_file_close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
root = doc->root;
|
||||
if(!root || strcasecmp(root->name,"pocketsphinx") != 0) {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root->name);
|
||||
apr_file_close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
apr_file_close(fd);
|
||||
return root;
|
||||
}
|
||||
|
||||
static apt_bool_t sensitivity_properties_load(pocketsphinx_properties_t *properties, const apr_xml_elem *elem, apr_pool_t *pool)
|
||||
{
|
||||
const apr_xml_attr *attr;
|
||||
for(attr = elem->attr; attr; attr = attr->next) {
|
||||
if(strcasecmp(attr->name,"level") == 0) {
|
||||
properties->sensitivity_level = atol(attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"timeout") == 0) {
|
||||
properties->sensitivity_timeout = atol(attr->value);
|
||||
}
|
||||
else {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static apt_bool_t timer_properties_load(pocketsphinx_properties_t *properties, const apr_xml_elem *elem, apr_pool_t *pool)
|
||||
{
|
||||
const apr_xml_attr *attr;
|
||||
for(attr = elem->attr; attr; attr = attr->next) {
|
||||
if(strcasecmp(attr->name,"noinput-timeout") == 0) {
|
||||
properties->no_input_timeout = atol(attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"recognition-timeout") == 0) {
|
||||
properties->recognition_timeout = atol(attr->value);
|
||||
}
|
||||
else {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static apt_bool_t model_properties_load(pocketsphinx_properties_t *properties, const apr_xml_elem *elem, apr_pool_t *pool)
|
||||
{
|
||||
const apr_xml_attr *attr;
|
||||
for(attr = elem->attr; attr; attr = attr->next) {
|
||||
if(strcasecmp(attr->name,"dir") == 0) {
|
||||
properties->data_dir = apr_pstrdup(pool,attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"narrowband") == 0) {
|
||||
properties->model_8k = apr_pstrdup(pool,attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"wideband") == 0) {
|
||||
properties->model_16k = apr_pstrdup(pool,attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"dictionary") == 0) {
|
||||
properties->dictionary = apr_pstrdup(pool,attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"preferred") == 0) {
|
||||
if(strcasecmp(attr->value,"narrowband") == 0) {
|
||||
properties->preferred_model = POCKETSPHINX_MODEL_NARROWBAND;
|
||||
}
|
||||
else if(strcasecmp(attr->value,"wideband") == 0) {
|
||||
properties->preferred_model = POCKETSPHINX_MODEL_WIDEBAND;
|
||||
}
|
||||
}
|
||||
else {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static apt_bool_t save_waveform_properties_load(pocketsphinx_properties_t *properties, const apr_xml_elem *elem, apr_pool_t *pool)
|
||||
{
|
||||
const apr_xml_attr *attr;
|
||||
for(attr = elem->attr; attr; attr = attr->next) {
|
||||
if(strcasecmp(attr->name,"dir") == 0) {
|
||||
properties->save_waveform_dir = apr_pstrdup(pool,attr->value);
|
||||
}
|
||||
else if(strcasecmp(attr->name,"enable") == 0) {
|
||||
properties->save_waveform = atoi(attr->value);
|
||||
}
|
||||
else {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
apt_bool_t pocketsphinx_properties_load(pocketsphinx_properties_t *properties,
|
||||
const char *file_path,
|
||||
const apt_dir_layout_t *dir_layout,
|
||||
apr_pool_t *pool)
|
||||
{
|
||||
const apr_xml_elem *elem;
|
||||
const apr_xml_elem *root;
|
||||
char *path = NULL;
|
||||
|
||||
/* reset or set default properties */
|
||||
properties->data_dir = NULL;
|
||||
properties->dictionary = NULL;
|
||||
properties->model_8k = NULL;
|
||||
properties->model_16k = NULL;
|
||||
properties->preferred_model = POCKETSPHINX_MODEL_NARROWBAND;
|
||||
|
||||
properties->no_input_timeout = 10000;
|
||||
properties->recognition_timeout = 15000;
|
||||
properties->partial_result_timeout = 100;
|
||||
|
||||
properties->save_waveform = TRUE;
|
||||
properties->save_waveform_dir = NULL;
|
||||
|
||||
root = pocketsphinx_document_load(file_path,pool);
|
||||
if(root) {
|
||||
for(elem = root->first_child; elem; elem = elem->next) {
|
||||
if(strcasecmp(elem->name,"sensitivity") == 0) {
|
||||
sensitivity_properties_load(properties,elem,pool);
|
||||
}
|
||||
else if(strcasecmp(elem->name,"timers") == 0) {
|
||||
timer_properties_load(properties,elem,pool);
|
||||
}
|
||||
else if(strcasecmp(elem->name,"model") == 0) {
|
||||
model_properties_load(properties,elem,pool);
|
||||
}
|
||||
else if(strcasecmp(elem->name,"save-waveform") == 0) {
|
||||
save_waveform_properties_load(properties,elem,pool);
|
||||
}
|
||||
else {
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* verify loaded properties */
|
||||
if(!properties->data_dir || *properties->data_dir == '\0') {
|
||||
properties->data_dir = dir_layout->data_dir_path;
|
||||
}
|
||||
if(!properties->save_waveform_dir || *properties->save_waveform_dir == '\0') {
|
||||
properties->save_waveform_dir = dir_layout->data_dir_path;
|
||||
}
|
||||
|
||||
if(!properties->dictionary) {
|
||||
properties->dictionary = "default.dic";
|
||||
}
|
||||
if(!properties->model_8k) {
|
||||
properties->model_8k = "communicator";
|
||||
}
|
||||
if(!properties->model_16k) {
|
||||
properties->model_16k = "wsj1";
|
||||
}
|
||||
|
||||
if(apr_filepath_merge(&path,properties->data_dir,properties->dictionary,0,pool) == APR_SUCCESS) {
|
||||
properties->dictionary = path;
|
||||
}
|
||||
if(apr_filepath_merge(&path,properties->data_dir,properties->model_8k,0,pool) == APR_SUCCESS) {
|
||||
properties->model_8k = path;
|
||||
}
|
||||
if(apr_filepath_merge(&path,properties->data_dir,properties->model_16k,0,pool) == APR_SUCCESS) {
|
||||
properties->model_16k = path;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
Reference in New Issue
Block a user