mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-12 20:47:06 +00:00
Update to latest UniMRCP version. MRCP requests can no timeout if there is no server response.
This commit is contained in:
1 parent
0555b702db
commit
17099473a3
441 files changed
+17430
-17071
No files matched your search
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: dtmfscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: dtmfsession.cpp 1780 2010-09-01 05:59:32Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "dtmfsession.h"
|
||||
@@ -30,8 +32,6 @@ struct RecogChannel
|
||||
mrcp_channel_t* m_pMrcpChannel;
|
||||
/** DTMF generator */
|
||||
mpf_dtmf_generator_t* m_pDtmfGenerator;
|
||||
/** Audio stream */
|
||||
mpf_audio_stream_t* m_pStream;
|
||||
/** Streaming is in-progress */
|
||||
bool m_Streaming;
|
||||
};
|
||||
@@ -79,13 +79,6 @@ bool DtmfSession::OnSessionTerminate(mrcp_sig_status_code_e status)
|
||||
return UmcSession::OnSessionTerminate(status);
|
||||
}
|
||||
|
||||
static apt_bool_t OpenStream(mpf_audio_stream_t* pStream, mpf_codec_t *codec)
|
||||
{
|
||||
RecogChannel* pRecogChannel = (RecogChannel*) pStream->obj;
|
||||
pRecogChannel->m_pStream = pStream;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static apt_bool_t ReadStream(mpf_audio_stream_t* pStream, mpf_frame_t* pFrame)
|
||||
{
|
||||
RecogChannel* pRecogChannel = (RecogChannel*) pStream->obj;
|
||||
@@ -110,7 +103,6 @@ RecogChannel* DtmfSession::CreateRecogChannel()
|
||||
RecogChannel *pRecogChannel = new RecogChannel;
|
||||
pRecogChannel->m_pMrcpChannel = NULL;
|
||||
pRecogChannel->m_pDtmfGenerator = NULL;
|
||||
pRecogChannel->m_pStream = NULL;
|
||||
pRecogChannel->m_Streaming = false;
|
||||
|
||||
/* create source stream capabilities */
|
||||
@@ -120,7 +112,7 @@ RecogChannel* DtmfSession::CreateRecogChannel()
|
||||
static const mpf_audio_stream_vtable_t audio_stream_vtable =
|
||||
{
|
||||
NULL,
|
||||
OpenStream,
|
||||
NULL,
|
||||
NULL,
|
||||
ReadStream,
|
||||
NULL,
|
||||
@@ -162,7 +154,11 @@ bool DtmfSession::OnChannelAdd(mrcp_channel_t* pMrcpChannel, mrcp_sig_status_cod
|
||||
RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pRecogChannel)
|
||||
{
|
||||
pRecogChannel->m_pDtmfGenerator = mpf_dtmf_generator_create(pRecogChannel->m_pStream,GetSessionPool());
|
||||
const mpf_audio_stream_t* pStream = mrcp_application_audio_stream_get(pMrcpChannel);
|
||||
if(pStream)
|
||||
{
|
||||
pRecogChannel->m_pDtmfGenerator = mpf_dtmf_generator_create(pStream,GetSessionPool());
|
||||
}
|
||||
}
|
||||
|
||||
return StartRecognition(pMrcpChannel);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: main.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "umcconsole.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: recogscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: recogsession.cpp 1587 2010-03-12 19:40:02Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "recogsession.h"
|
||||
@@ -27,12 +29,21 @@ struct RecogChannel
|
||||
{
|
||||
/** MRCP control channel */
|
||||
mrcp_channel_t* m_pMrcpChannel;
|
||||
/** IN-PROGRESS RECOGNIZE request */
|
||||
mrcp_message_t* m_pRecogRequest;
|
||||
/** Streaming is in-progress */
|
||||
bool m_Streaming;
|
||||
/** File to read audio stream from */
|
||||
FILE* m_pAudioIn;
|
||||
/** Estimated time to complete (used if no audio_in available) */
|
||||
apr_size_t m_TimeToComplete;
|
||||
|
||||
RecogChannel() :
|
||||
m_pMrcpChannel(NULL),
|
||||
m_pRecogRequest(NULL),
|
||||
m_Streaming(false),
|
||||
m_pAudioIn(NULL),
|
||||
m_TimeToComplete(0) {}
|
||||
};
|
||||
|
||||
RecogSession::RecogSession(const RecogScenario* pScenario) :
|
||||
@@ -67,6 +78,37 @@ bool RecogSession::Start()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RecogSession::Stop()
|
||||
{
|
||||
if(!UmcSession::Stop())
|
||||
return false;
|
||||
|
||||
if(!m_pRecogChannel)
|
||||
return false;
|
||||
|
||||
mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pRecogChannel->m_pMrcpChannel,RECOGNIZER_STOP);
|
||||
if(!pStopMessage)
|
||||
return false;
|
||||
|
||||
if(m_pRecogChannel->m_pRecogRequest)
|
||||
{
|
||||
mrcp_generic_header_t* pGenericHeader;
|
||||
/* get/allocate generic header */
|
||||
pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pStopMessage);
|
||||
if(pGenericHeader)
|
||||
{
|
||||
pGenericHeader->active_request_id_list.count = 1;
|
||||
pGenericHeader->active_request_id_list.ids[0] =
|
||||
m_pRecogChannel->m_pRecogRequest->start_line.request_id;
|
||||
mrcp_generic_header_property_add(pStopMessage,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST);
|
||||
}
|
||||
|
||||
m_pRecogChannel->m_pRecogRequest = NULL;
|
||||
}
|
||||
|
||||
return SendMrcpRequest(m_pRecogChannel->m_pMrcpChannel,pStopMessage);
|
||||
}
|
||||
|
||||
bool RecogSession::OnSessionTerminate(mrcp_sig_status_code_e status)
|
||||
{
|
||||
if(m_pRecogChannel)
|
||||
@@ -128,11 +170,7 @@ RecogChannel* RecogSession::CreateRecogChannel()
|
||||
apr_pool_t* pool = GetSessionPool();
|
||||
|
||||
/* create channel */
|
||||
RecogChannel *pRecogChannel = new RecogChannel;
|
||||
pRecogChannel->m_pMrcpChannel = NULL;
|
||||
pRecogChannel->m_Streaming = false;
|
||||
pRecogChannel->m_pAudioIn = NULL;
|
||||
pRecogChannel->m_TimeToComplete = 0;
|
||||
RecogChannel* pRecogChannel = new RecogChannel;
|
||||
|
||||
/* create source stream capabilities */
|
||||
pCapabilities = mpf_source_stream_capabilities_create(pool);
|
||||
@@ -218,11 +256,13 @@ bool RecogSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t
|
||||
/* received the response to RECOGNIZE request */
|
||||
if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS)
|
||||
{
|
||||
RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pRecogChannel)
|
||||
pRecogChannel->m_pRecogRequest = GetMrcpMessage();
|
||||
|
||||
/* start to stream the speech to recognize */
|
||||
if(pRecogChannel)
|
||||
{
|
||||
pRecogChannel->m_Streaming = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,9 +281,12 @@ bool RecogSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t
|
||||
{
|
||||
ParseNLSMLResult(pMrcpMessage);
|
||||
if(pRecogChannel)
|
||||
{
|
||||
pRecogChannel->m_Streaming = false;
|
||||
}
|
||||
|
||||
RecogChannel* pRecogChannel = (RecogChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pRecogChannel)
|
||||
pRecogChannel->m_pRecogRequest = NULL;
|
||||
|
||||
Terminate();
|
||||
}
|
||||
else if(pMrcpMessage->start_line.method_id == RECOGNIZER_START_OF_INPUT)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: recorderscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: recordersession.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "recordersession.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: setparamscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "setparamscenario.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: setparamsession.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "setparamsession.h"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: synthscenario.cpp 1474 2010-02-07 20:51:47Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: synthsession.cpp 1586 2010-03-12 19:39:02Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "synthsession.h"
|
||||
@@ -23,9 +25,14 @@
|
||||
|
||||
struct SynthChannel
|
||||
{
|
||||
/** MRCP channel */
|
||||
mrcp_channel_t* m_pMrcpChannel;
|
||||
/** IN-PROGRESS SPEAK request */
|
||||
mrcp_message_t* m_pSpeakRequest;
|
||||
/** File to write audio stream to */
|
||||
FILE* m_pAudioOut;
|
||||
|
||||
SynthChannel() : m_pMrcpChannel(NULL), m_pSpeakRequest(NULL), m_pAudioOut(NULL) {}
|
||||
};
|
||||
|
||||
SynthSession::SynthSession(const SynthScenario* pScenario) :
|
||||
@@ -58,6 +65,37 @@ bool SynthSession::Start()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SynthSession::Stop()
|
||||
{
|
||||
if(!UmcSession::Stop())
|
||||
return false;
|
||||
|
||||
if(!m_pSynthChannel)
|
||||
return false;
|
||||
|
||||
mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pSynthChannel->m_pMrcpChannel,SYNTHESIZER_STOP);
|
||||
if(!pStopMessage)
|
||||
return false;
|
||||
|
||||
if(m_pSynthChannel->m_pSpeakRequest)
|
||||
{
|
||||
mrcp_generic_header_t* pGenericHeader;
|
||||
/* get/allocate generic header */
|
||||
pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pStopMessage);
|
||||
if(pGenericHeader)
|
||||
{
|
||||
pGenericHeader->active_request_id_list.count = 1;
|
||||
pGenericHeader->active_request_id_list.ids[0] =
|
||||
m_pSynthChannel->m_pSpeakRequest->start_line.request_id;
|
||||
mrcp_generic_header_property_add(pStopMessage,GENERIC_HEADER_ACTIVE_REQUEST_ID_LIST);
|
||||
}
|
||||
|
||||
m_pSynthChannel->m_pSpeakRequest = NULL;
|
||||
}
|
||||
|
||||
return SendMrcpRequest(m_pSynthChannel->m_pMrcpChannel,pStopMessage);
|
||||
}
|
||||
|
||||
bool SynthSession::OnSessionTerminate(mrcp_sig_status_code_e status)
|
||||
{
|
||||
if(m_pSynthChannel)
|
||||
@@ -93,8 +131,7 @@ SynthChannel* SynthSession::CreateSynthChannel()
|
||||
apr_pool_t* pool = GetSessionPool();
|
||||
|
||||
/* create channel */
|
||||
SynthChannel *pSynthChannel = new SynthChannel;
|
||||
pSynthChannel->m_pMrcpChannel = NULL;
|
||||
SynthChannel* pSynthChannel = new SynthChannel;
|
||||
|
||||
/* create sink stream capabilities */
|
||||
pCapabilities = mpf_sink_stream_capabilities_create(pool);
|
||||
@@ -128,7 +165,6 @@ SynthChannel* SynthSession::CreateSynthChannel()
|
||||
}
|
||||
|
||||
pSynthChannel->m_pMrcpChannel = pChannel;
|
||||
pSynthChannel->m_pAudioOut = NULL;
|
||||
return pSynthChannel;
|
||||
}
|
||||
|
||||
@@ -169,6 +205,10 @@ bool SynthSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t
|
||||
/* received the response to SPEAK request */
|
||||
if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS)
|
||||
{
|
||||
SynthChannel* pSynthChannel = (SynthChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pSynthChannel)
|
||||
pSynthChannel->m_pSpeakRequest = GetMrcpMessage();
|
||||
|
||||
/* waiting for SPEAK-COMPLETE event */
|
||||
}
|
||||
else
|
||||
@@ -187,6 +227,9 @@ bool SynthSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t
|
||||
/* received MRCP event */
|
||||
if(pMrcpMessage->start_line.method_id == SYNTHESIZER_SPEAK_COMPLETE)
|
||||
{
|
||||
SynthChannel* pSynthChannel = (SynthChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pSynthChannel)
|
||||
pSynthChannel->m_pSpeakRequest = NULL;
|
||||
/* received SPEAK-COMPLETE event, terminate the session */
|
||||
Terminate();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: umcconsole.cpp 1785 2010-09-22 06:14:29Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -37,6 +39,7 @@ bool UmcConsole::Run(int argc, const char * const *argv)
|
||||
{
|
||||
apr_pool_t* pool = NULL;
|
||||
apt_dir_layout_t* pDirLayout = NULL;
|
||||
const char *logConfPath;
|
||||
|
||||
/* APR global initialization */
|
||||
if(apr_initialize() != APR_SUCCESS)
|
||||
@@ -63,13 +66,27 @@ bool UmcConsole::Run(int argc, const char * const *argv)
|
||||
|
||||
/* create the structure of default directories layout */
|
||||
pDirLayout = apt_default_dir_layout_create(m_Options.m_RootDirPath,pool);
|
||||
/* create singleton logger */
|
||||
apt_log_instance_create(m_Options.m_LogOutput,m_Options.m_LogPriority,pool);
|
||||
|
||||
if((m_Options.m_LogOutput & APT_LOG_OUTPUT_FILE) == APT_LOG_OUTPUT_FILE)
|
||||
/* get path to logger configuration file */
|
||||
logConfPath = apt_confdir_filepath_get(pDirLayout,"logger.xml",pool);
|
||||
/* create and load singleton logger */
|
||||
apt_log_instance_load(logConfPath,pool);
|
||||
|
||||
if(m_Options.m_LogPriority)
|
||||
{
|
||||
/* override the log priority, if specified in command line */
|
||||
apt_log_priority_set((apt_log_priority_e)atoi(m_Options.m_LogPriority));
|
||||
}
|
||||
if(m_Options.m_LogOutput)
|
||||
{
|
||||
/* override the log output mode, if specified in command line */
|
||||
apt_log_output_mode_set((apt_log_output_e)atoi(m_Options.m_LogOutput));
|
||||
}
|
||||
|
||||
if(apt_log_output_mode_check(APT_LOG_OUTPUT_FILE) == TRUE)
|
||||
{
|
||||
/* open the log file */
|
||||
apt_log_file_open(pDirLayout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,pool);
|
||||
apt_log_file_open(pDirLayout->log_dir_path,"unimrcpclient",MAX_LOG_FILE_SIZE,MAX_LOG_FILE_COUNT,FALSE,pool);
|
||||
}
|
||||
|
||||
/* create demo framework */
|
||||
@@ -105,7 +122,7 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine)
|
||||
const char* pProfileName = apr_strtok(NULL, " ", &last);
|
||||
if(!pProfileName)
|
||||
{
|
||||
pProfileName = "MRCPv2-Default";
|
||||
pProfileName = "uni2";
|
||||
}
|
||||
m_pFramework->RunSession(pScenarioName,pProfileName);
|
||||
}
|
||||
@@ -118,6 +135,14 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine)
|
||||
m_pFramework->KillSession(pID);
|
||||
}
|
||||
}
|
||||
else if(strcasecmp(name,"stop") == 0)
|
||||
{
|
||||
char* pID = apr_strtok(NULL, " ", &last);
|
||||
if(pID)
|
||||
{
|
||||
m_pFramework->StopSession(pID);
|
||||
}
|
||||
}
|
||||
else if(strcasecmp(name,"show") == 0)
|
||||
{
|
||||
char* pWhat = apr_strtok(NULL, " ", &last);
|
||||
@@ -146,12 +171,12 @@ bool UmcConsole::ProcessCmdLine(char* pCmdLine)
|
||||
printf("usage:\n"
|
||||
"\n- run [scenario] [profile] (run new session)\n"
|
||||
" scenario is one of 'synth', 'recog', ... (use 'show scenarios')\n"
|
||||
" profile is one of 'MRCPv2-Default', 'MRCPv1-Default', ... (see unimrcpclient.xml)\n"
|
||||
" profile is one of 'uni2', 'uni1', ... (see unimrcpclient.xml)\n"
|
||||
"\n examples: \n"
|
||||
" run synth\n"
|
||||
" run recog\n"
|
||||
" run synth MRCPv1-Default\n"
|
||||
" run recog MRCPv1-Default\n"
|
||||
" run synth uni1\n"
|
||||
" run recog uni1\n"
|
||||
"\n- kill [id] (kill session)\n"
|
||||
" id is a session identifier: 1, 2, ... (use 'show sessions')\n"
|
||||
"\n example: \n"
|
||||
@@ -238,8 +263,8 @@ bool UmcConsole::LoadOptions(int argc, const char * const *argv, apr_pool_t *poo
|
||||
|
||||
/* set the default options */
|
||||
m_Options.m_RootDirPath = "../";
|
||||
m_Options.m_LogPriority = APT_PRIO_INFO;
|
||||
m_Options.m_LogOutput = APT_LOG_OUTPUT_CONSOLE;
|
||||
m_Options.m_LogPriority = NULL;
|
||||
m_Options.m_LogOutput = NULL;
|
||||
|
||||
rv = apr_getopt_init(&opt, pool , argc, argv);
|
||||
if(rv != APR_SUCCESS)
|
||||
@@ -254,15 +279,11 @@ bool UmcConsole::LoadOptions(int argc, const char * const *argv, apr_pool_t *poo
|
||||
break;
|
||||
case 'l':
|
||||
if(optarg)
|
||||
{
|
||||
m_Options.m_LogPriority = (apt_log_priority_e) atoi(optarg);
|
||||
}
|
||||
m_Options.m_LogPriority = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
if(optarg)
|
||||
{
|
||||
m_Options.m_LogOutput = (apt_log_output_e) atoi(optarg);
|
||||
}
|
||||
m_Options.m_LogOutput = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
Usage();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,6 +12,8 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: umcframework.cpp 1767 2010-08-23 19:10:22Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "umcframework.h"
|
||||
@@ -21,6 +23,7 @@
|
||||
#include "recorderscenario.h"
|
||||
#include "dtmfscenario.h"
|
||||
#include "setparamscenario.h"
|
||||
#include "verifierscenario.h"
|
||||
#include "unimrcp_client.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
@@ -36,6 +39,7 @@ enum UmcTaskMsgType
|
||||
{
|
||||
UMC_TASK_CLIENT_MSG,
|
||||
UMC_TASK_RUN_SESSION_MSG,
|
||||
UMC_TASK_STOP_SESSION_MSG,
|
||||
UMC_TASK_KILL_SESSION_MSG,
|
||||
UMC_TASK_SHOW_SCENARIOS_MSG,
|
||||
UMC_TASK_SHOW_SESSIONS_MSG
|
||||
@@ -134,7 +138,7 @@ bool UmcFramework::CreateTask()
|
||||
return false;
|
||||
|
||||
pTask = apt_consumer_task_base_get(m_pTask);
|
||||
apt_task_name_set(pTask,"Framework Task");
|
||||
apt_task_name_set(pTask,"Framework Agent");
|
||||
pVtable = apt_consumer_task_vtable_get(m_pTask);
|
||||
if(pVtable)
|
||||
{
|
||||
@@ -175,6 +179,8 @@ UmcScenario* UmcFramework::CreateScenario(const char* pType)
|
||||
return new DtmfScenario();
|
||||
else if(strcasecmp(pType,"Params") == 0)
|
||||
return new SetParamScenario();
|
||||
else if(strcasecmp(pType,"Verifier") == 0)
|
||||
return new VerifierScenario();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -335,6 +341,24 @@ bool UmcFramework::ProcessRunRequest(const char* pScenarioName, const char* pPro
|
||||
return true;
|
||||
}
|
||||
|
||||
void UmcFramework::ProcessStopRequest(const char* id)
|
||||
{
|
||||
UmcSession* pSession;
|
||||
void* pVal;
|
||||
apr_hash_index_t* it = apr_hash_first(m_pPool,m_pSessionTable);
|
||||
for(; it; it = apr_hash_next(it))
|
||||
{
|
||||
apr_hash_this(it,NULL,NULL,&pVal);
|
||||
pSession = (UmcSession*) pVal;
|
||||
if(pSession && strcasecmp(pSession->GetId(),id) == 0)
|
||||
{
|
||||
/* stop in-progress request */
|
||||
pSession->Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UmcFramework::ProcessKillRequest(const char* id)
|
||||
{
|
||||
UmcSession* pSession;
|
||||
@@ -346,7 +370,7 @@ void UmcFramework::ProcessKillRequest(const char* id)
|
||||
pSession = (UmcSession*) pVal;
|
||||
if(pSession && strcasecmp(pSession->GetId(),id) == 0)
|
||||
{
|
||||
/* first, terminate session */
|
||||
/* terminate session */
|
||||
pSession->Terminate();
|
||||
return;
|
||||
}
|
||||
@@ -403,6 +427,22 @@ void UmcFramework::RunSession(const char* pScenarioName, const char* pProfileNam
|
||||
apt_task_msg_signal(pTask,pTaskMsg);
|
||||
}
|
||||
|
||||
void UmcFramework::StopSession(const char* id)
|
||||
{
|
||||
apt_task_t* pTask = apt_consumer_task_base_get(m_pTask);
|
||||
apt_task_msg_t* pTaskMsg = apt_task_msg_get(pTask);
|
||||
if(!pTaskMsg)
|
||||
return;
|
||||
|
||||
pTaskMsg->type = TASK_MSG_USER;
|
||||
pTaskMsg->sub_type = UMC_TASK_STOP_SESSION_MSG;
|
||||
|
||||
UmcTaskMsg* pUmcMsg = (UmcTaskMsg*) pTaskMsg->data;
|
||||
strncpy(pUmcMsg->m_SessionId,id,sizeof(pUmcMsg->m_SessionId)-1);
|
||||
pUmcMsg->m_pAppMessage = NULL;
|
||||
apt_task_msg_signal(pTask,pTaskMsg);
|
||||
}
|
||||
|
||||
void UmcFramework::KillSession(const char* id)
|
||||
{
|
||||
apt_task_t* pTask = apt_consumer_task_base_get(m_pTask);
|
||||
@@ -562,6 +602,11 @@ apt_bool_t UmcProcessMsg(apt_task_t *pTask, apt_task_msg_t *pMsg)
|
||||
pFramework->ProcessRunRequest(pUmcMsg->m_ScenarioName,pUmcMsg->m_ProfileName);
|
||||
break;
|
||||
}
|
||||
case UMC_TASK_STOP_SESSION_MSG:
|
||||
{
|
||||
pFramework->ProcessStopRequest(pUmcMsg->m_SessionId);
|
||||
break;
|
||||
}
|
||||
case UMC_TASK_KILL_SESSION_MSG:
|
||||
{
|
||||
pFramework->ProcessKillRequest(pUmcMsg->m_SessionId);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,14 +12,17 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: umcscenario.cpp 1571 2010-03-07 20:33:39Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "umcscenario.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
UmcScenario::UmcScenario() :
|
||||
m_pName(NULL),
|
||||
m_pMrcpProfile("MRCPv2-Default"),
|
||||
m_pMrcpProfile("uni2"),
|
||||
m_pDirLayout(NULL),
|
||||
m_ResourceDiscovery(false),
|
||||
m_pCapabilities(NULL),
|
||||
@@ -200,14 +203,31 @@ const char* UmcScenario::LoadFileContent(const char* pFileName, apr_pool_t* pool
|
||||
if(!pFilePath)
|
||||
return NULL;
|
||||
|
||||
FILE* pFile = fopen(pFilePath,"r");
|
||||
if(!pFile)
|
||||
apr_file_t *pFile;
|
||||
if(apr_file_open(&pFile,pFilePath,APR_FOPEN_READ|APR_FOPEN_BINARY,0,pool) != APR_SUCCESS)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open File %s",pFilePath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char text[1024];
|
||||
apr_size_t size;
|
||||
size = fread(text,1,sizeof(text)-1,pFile);
|
||||
text[size] = '\0';
|
||||
fclose(pFile);
|
||||
return apr_pstrdup(pool,text);
|
||||
apr_finfo_t finfo;
|
||||
if(apr_file_info_get(&finfo,APR_FINFO_SIZE,pFile) != APR_SUCCESS)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Get File Info %s",pFilePath);
|
||||
apr_file_close(pFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
apr_size_t size = (apr_size_t)finfo.size;
|
||||
char* pContent = (char*) apr_palloc(pool,size+1);
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Load File Content size [%"APR_SIZE_T_FMT" bytes] %s",size,pFilePath);
|
||||
if(apr_file_read(pFile,pContent,&size) != APR_SUCCESS)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Read Content %s",pFilePath);
|
||||
apr_file_close(pFile);
|
||||
return NULL;
|
||||
}
|
||||
pContent[size] = '\0';
|
||||
apr_file_close(pFile);
|
||||
return pContent;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Arsen Chaloyan
|
||||
* Copyright 2008-2010 Arsen Chaloyan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -12,16 +12,20 @@
|
||||
* 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.
|
||||
*
|
||||
* $Id: umcsession.cpp 1695 2010-05-19 18:56:15Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "umcsession.h"
|
||||
#include "umcscenario.h"
|
||||
#include "mrcp_message.h"
|
||||
|
||||
UmcSession::UmcSession(const UmcScenario* pScenario) :
|
||||
m_pScenario(pScenario),
|
||||
m_pMrcpProfile(NULL),
|
||||
m_pMrcpApplication(NULL),
|
||||
m_pMrcpSession(NULL),
|
||||
m_pMrcpMessage(NULL),
|
||||
m_Running(false),
|
||||
m_Terminating(false)
|
||||
{
|
||||
@@ -69,6 +73,14 @@ bool UmcSession::Run()
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool UmcSession::Stop()
|
||||
{
|
||||
if(m_Terminating)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UmcSession::Terminate()
|
||||
{
|
||||
if(m_Terminating)
|
||||
@@ -105,7 +117,17 @@ bool UmcSession::OnChannelRemove(mrcp_channel_t *channel, mrcp_sig_status_code_e
|
||||
|
||||
bool UmcSession::OnMessageReceive(mrcp_channel_t *channel, mrcp_message_t *message)
|
||||
{
|
||||
return m_Running;
|
||||
if(!m_Running)
|
||||
return false;
|
||||
|
||||
if(!m_pMrcpMessage)
|
||||
return false;
|
||||
|
||||
/* match request identifiers */
|
||||
if(m_pMrcpMessage->start_line.request_id != message->start_line.request_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UmcSession::OnTerminateEvent(mrcp_channel_t *channel)
|
||||
@@ -129,6 +151,9 @@ bool UmcSession::OnResourceDiscover(mrcp_session_descriptor_t* descriptor, mrcp_
|
||||
bool UmcSession::CreateMrcpSession(const char* pProfileName)
|
||||
{
|
||||
m_pMrcpSession = mrcp_application_session_create(m_pMrcpApplication,pProfileName,this);
|
||||
char name[32];
|
||||
apr_snprintf(name,sizeof(name),"umc-%s",m_Id);
|
||||
mrcp_application_session_name_set(m_pMrcpSession,name);
|
||||
return (m_pMrcpSession != NULL);
|
||||
}
|
||||
|
||||
@@ -163,6 +188,7 @@ bool UmcSession::SendMrcpRequest(mrcp_channel_t* pMrcpChannel, mrcp_message_t* p
|
||||
if(!m_Running)
|
||||
return false;
|
||||
|
||||
m_pMrcpMessage = pMrcpMessage;
|
||||
return (mrcp_application_message_send(m_pMrcpSession,pMrcpChannel,pMrcpMessage) == TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2008-2010 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.
|
||||
*
|
||||
* $Id: verifierscenario.cpp 1775 2010-08-26 18:23:38Z achaloyan $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "verifierscenario.h"
|
||||
#include "verifiersession.h"
|
||||
#include "mrcp_message.h"
|
||||
#include "mrcp_generic_header.h"
|
||||
#include "mrcp_recog_header.h"
|
||||
#include "mrcp_recog_resource.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
VerifierScenario::VerifierScenario() :
|
||||
m_RepositoryURI(NULL),
|
||||
m_VerificationMode(NULL),
|
||||
m_VoiceprintIdentifier(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
VerifierScenario::~VerifierScenario()
|
||||
{
|
||||
}
|
||||
|
||||
void VerifierScenario::Destroy()
|
||||
{
|
||||
}
|
||||
|
||||
bool VerifierScenario::LoadElement(const apr_xml_elem* pElem, apr_pool_t* pool)
|
||||
{
|
||||
if(UmcScenario::LoadElement(pElem,pool))
|
||||
return true;
|
||||
|
||||
if(strcasecmp(pElem->name,"verify") == 0)
|
||||
{
|
||||
LoadVerify(pElem,pool);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifierScenario::LoadVerify(const apr_xml_elem* pElem, apr_pool_t* pool)
|
||||
{
|
||||
const apr_xml_attr* pAttr;
|
||||
for(pAttr = pElem->attr; pAttr; pAttr = pAttr->next)
|
||||
{
|
||||
if(strcasecmp(pAttr->name,"repository-uri") == 0)
|
||||
{
|
||||
m_RepositoryURI = pAttr->value;
|
||||
}
|
||||
else if(strcasecmp(pAttr->name,"verification-mode") == 0)
|
||||
{
|
||||
m_VerificationMode = pAttr->value;
|
||||
}
|
||||
else if(strcasecmp(pAttr->name,"voiceprint-identifier") == 0)
|
||||
{
|
||||
m_VoiceprintIdentifier = pAttr->value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
UmcSession* VerifierScenario::CreateSession()
|
||||
{
|
||||
return new VerifierSession(this);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
/*
|
||||
* Copyright 2008-2010 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.
|
||||
*
|
||||
* $Id: verifiersession.cpp 1778 2010-08-27 17:34:52Z achaloyan $
|
||||
*/
|
||||
|
||||
#include "verifiersession.h"
|
||||
#include "verifierscenario.h"
|
||||
#include "mrcp_message.h"
|
||||
#include "mrcp_generic_header.h"
|
||||
#include "mrcp_verifier_header.h"
|
||||
#include "mrcp_verifier_resource.h"
|
||||
#include "apt_nlsml_doc.h"
|
||||
#include "apt_log.h"
|
||||
|
||||
struct VerifierChannel
|
||||
{
|
||||
/** MRCP control channel */
|
||||
mrcp_channel_t* m_pMrcpChannel;
|
||||
/** IN-PROGRESS VERIFY request */
|
||||
mrcp_message_t* m_pVerificationRequest;
|
||||
/** Streaming is in-progress */
|
||||
bool m_Streaming;
|
||||
/** File to read audio stream from */
|
||||
FILE* m_pAudioIn;
|
||||
/** Estimated time to complete (used if no audio_in available) */
|
||||
apr_size_t m_TimeToComplete;
|
||||
|
||||
VerifierChannel() :
|
||||
m_pMrcpChannel(NULL),
|
||||
m_pVerificationRequest(NULL),
|
||||
m_Streaming(false),
|
||||
m_pAudioIn(NULL),
|
||||
m_TimeToComplete(0) {}
|
||||
};
|
||||
|
||||
VerifierSession::VerifierSession(const VerifierScenario* pScenario) :
|
||||
UmcSession(pScenario),
|
||||
m_pVerifierChannel(NULL),
|
||||
m_ContentId("request1@form-level")
|
||||
{
|
||||
}
|
||||
|
||||
VerifierSession::~VerifierSession()
|
||||
{
|
||||
}
|
||||
|
||||
bool VerifierSession::Start()
|
||||
{
|
||||
/* create channel and associate all the required data */
|
||||
m_pVerifierChannel = CreateVerifierChannel();
|
||||
if(!m_pVerifierChannel)
|
||||
return false;
|
||||
|
||||
/* add channel to session (send asynchronous request) */
|
||||
if(!AddMrcpChannel(m_pVerifierChannel->m_pMrcpChannel))
|
||||
{
|
||||
delete m_pVerifierChannel;
|
||||
m_pVerifierChannel = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifierSession::Stop()
|
||||
{
|
||||
if(!UmcSession::Stop())
|
||||
return false;
|
||||
|
||||
if(!m_pVerifierChannel)
|
||||
return false;
|
||||
|
||||
mrcp_message_t* pStopMessage = CreateMrcpMessage(m_pVerifierChannel->m_pMrcpChannel,VERIFIER_STOP);
|
||||
if(!pStopMessage)
|
||||
return false;
|
||||
|
||||
return SendMrcpRequest(m_pVerifierChannel->m_pMrcpChannel,pStopMessage);
|
||||
}
|
||||
|
||||
bool VerifierSession::OnSessionTerminate(mrcp_sig_status_code_e status)
|
||||
{
|
||||
if(m_pVerifierChannel)
|
||||
{
|
||||
FILE* pAudioIn = m_pVerifierChannel->m_pAudioIn;
|
||||
if(pAudioIn)
|
||||
{
|
||||
m_pVerifierChannel->m_pAudioIn = NULL;
|
||||
fclose(pAudioIn);
|
||||
}
|
||||
|
||||
delete m_pVerifierChannel;
|
||||
m_pVerifierChannel = NULL;
|
||||
}
|
||||
return UmcSession::OnSessionTerminate(status);
|
||||
}
|
||||
|
||||
static apt_bool_t ReadStream(mpf_audio_stream_t* pStream, mpf_frame_t* pFrame)
|
||||
{
|
||||
VerifierChannel* pVerifierChannel = (VerifierChannel*) pStream->obj;
|
||||
if(pVerifierChannel && pVerifierChannel->m_Streaming)
|
||||
{
|
||||
if(pVerifierChannel->m_pAudioIn)
|
||||
{
|
||||
if(fread(pFrame->codec_frame.buffer,1,pFrame->codec_frame.size,pVerifierChannel->m_pAudioIn) == pFrame->codec_frame.size)
|
||||
{
|
||||
/* normal read */
|
||||
pFrame->type |= MEDIA_FRAME_TYPE_AUDIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* file is over */
|
||||
pVerifierChannel->m_Streaming = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fill with silence in case no file available */
|
||||
if(pVerifierChannel->m_TimeToComplete >= CODEC_FRAME_TIME_BASE)
|
||||
{
|
||||
pFrame->type |= MEDIA_FRAME_TYPE_AUDIO;
|
||||
memset(pFrame->codec_frame.buffer,0,pFrame->codec_frame.size);
|
||||
pVerifierChannel->m_TimeToComplete -= CODEC_FRAME_TIME_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pVerifierChannel->m_Streaming = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VerifierChannel* VerifierSession::CreateVerifierChannel()
|
||||
{
|
||||
mrcp_channel_t* pChannel;
|
||||
mpf_termination_t* pTermination;
|
||||
mpf_stream_capabilities_t* pCapabilities;
|
||||
apr_pool_t* pool = GetSessionPool();
|
||||
|
||||
/* create channel */
|
||||
VerifierChannel* pVerifierChannel = new VerifierChannel;
|
||||
|
||||
/* create source stream capabilities */
|
||||
pCapabilities = mpf_source_stream_capabilities_create(pool);
|
||||
GetScenario()->InitCapabilities(pCapabilities);
|
||||
|
||||
static const mpf_audio_stream_vtable_t audio_stream_vtable =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ReadStream,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
pTermination = CreateAudioTermination(
|
||||
&audio_stream_vtable, /* virtual methods table of audio stream */
|
||||
pCapabilities, /* capabilities of audio stream */
|
||||
pVerifierChannel); /* object to associate */
|
||||
|
||||
pChannel = CreateMrcpChannel(
|
||||
MRCP_VERIFIER_RESOURCE, /* MRCP resource identifier */
|
||||
pTermination, /* media termination, used to terminate audio stream */
|
||||
NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */
|
||||
pVerifierChannel); /* object to associate */
|
||||
if(!pChannel)
|
||||
{
|
||||
delete pVerifierChannel;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVerifierChannel->m_pMrcpChannel = pChannel;
|
||||
return pVerifierChannel;
|
||||
}
|
||||
|
||||
bool VerifierSession::OnChannelAdd(mrcp_channel_t* pMrcpChannel, mrcp_sig_status_code_e status)
|
||||
{
|
||||
if(!UmcSession::OnChannelAdd(pMrcpChannel,status))
|
||||
return false;
|
||||
|
||||
if(status != MRCP_SIG_STATUS_CODE_SUCCESS)
|
||||
{
|
||||
/* error case, just terminate the demo */
|
||||
return Terminate();
|
||||
}
|
||||
|
||||
return StartVerification(pMrcpChannel);
|
||||
}
|
||||
|
||||
bool VerifierSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t* pMrcpMessage)
|
||||
{
|
||||
if(!UmcSession::OnMessageReceive(pMrcpChannel,pMrcpMessage))
|
||||
return false;
|
||||
|
||||
VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pMrcpMessage->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE)
|
||||
{
|
||||
/* received MRCP response */
|
||||
if(pMrcpMessage->start_line.method_id == VERIFIER_START_SESSION)
|
||||
{
|
||||
/* received the response to START-SESSION request */
|
||||
/* create and send VERIFY request */
|
||||
mrcp_message_t* pMrcpMessage = CreateVerificationRequest(pMrcpChannel);
|
||||
if(pMrcpMessage)
|
||||
{
|
||||
SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage);
|
||||
}
|
||||
}
|
||||
else if(pMrcpMessage->start_line.method_id == VERIFIER_END_SESSION)
|
||||
{
|
||||
/* received the response to END-SESSION request */
|
||||
Terminate();
|
||||
}
|
||||
else if(pMrcpMessage->start_line.method_id == VERIFIER_VERIFY)
|
||||
{
|
||||
/* received the response to VERIFY request */
|
||||
if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_INPROGRESS)
|
||||
{
|
||||
VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pVerifierChannel)
|
||||
pVerifierChannel->m_pVerificationRequest = GetMrcpMessage();
|
||||
|
||||
/* start to stream the speech to Verify */
|
||||
if(pVerifierChannel)
|
||||
pVerifierChannel->m_Streaming = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create and send END-SESSION request */
|
||||
mrcp_message_t* pMrcpMessage = CreateEndSessionRequest(pMrcpChannel);
|
||||
if(pMrcpMessage)
|
||||
{
|
||||
SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* received unexpected response */
|
||||
}
|
||||
}
|
||||
else if(pMrcpMessage->start_line.message_type == MRCP_MESSAGE_TYPE_EVENT)
|
||||
{
|
||||
if(pMrcpMessage->start_line.method_id == VERIFIER_VERIFICATION_COMPLETE)
|
||||
{
|
||||
if(pVerifierChannel)
|
||||
pVerifierChannel->m_Streaming = false;
|
||||
|
||||
VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
if(pVerifierChannel)
|
||||
pVerifierChannel->m_pVerificationRequest = NULL;
|
||||
|
||||
/* create and send END-SESSION request */
|
||||
mrcp_message_t* pMrcpMessage = CreateEndSessionRequest(pMrcpChannel);
|
||||
if(pMrcpMessage)
|
||||
{
|
||||
SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage);
|
||||
}
|
||||
}
|
||||
else if(pMrcpMessage->start_line.method_id == VERIFIER_START_OF_INPUT)
|
||||
{
|
||||
/* received start-of-input, do whatever you need here */
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VerifierSession::StartVerification(mrcp_channel_t* pMrcpChannel)
|
||||
{
|
||||
VerifierChannel* pVerifierChannel = (VerifierChannel*) mrcp_application_channel_object_get(pMrcpChannel);
|
||||
/* create and send Verification request */
|
||||
mrcp_message_t* pMrcpMessage = CreateStartSessionRequest(pMrcpChannel);
|
||||
if(pMrcpMessage)
|
||||
{
|
||||
SendMrcpRequest(pVerifierChannel->m_pMrcpChannel,pMrcpMessage);
|
||||
}
|
||||
|
||||
const mpf_codec_descriptor_t* pDescriptor = mrcp_application_source_descriptor_get(pMrcpChannel);
|
||||
pVerifierChannel->m_pAudioIn = GetAudioIn(pDescriptor,GetSessionPool());
|
||||
if(!pVerifierChannel->m_pAudioIn)
|
||||
{
|
||||
/* no audio input availble, set some estimated time to complete instead */
|
||||
pVerifierChannel->m_TimeToComplete = 5000; // 5 sec
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mrcp_message_t* VerifierSession::CreateStartSessionRequest(mrcp_channel_t* pMrcpChannel)
|
||||
{
|
||||
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,VERIFIER_START_SESSION);
|
||||
if(!pMrcpMessage)
|
||||
return NULL;
|
||||
|
||||
mrcp_verifier_header_t* pVerifierHeader;
|
||||
|
||||
/* get/allocate verifier header */
|
||||
pVerifierHeader = (mrcp_verifier_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
|
||||
if(pVerifierHeader)
|
||||
{
|
||||
const VerifierScenario* pScenario = GetScenario();
|
||||
const char* pRepositoryURI = pScenario->GetRepositoryURI();
|
||||
if(pRepositoryURI)
|
||||
{
|
||||
apt_string_set(&pVerifierHeader->repository_uri,pRepositoryURI);
|
||||
mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_REPOSITORY_URI);
|
||||
}
|
||||
const char* pVoiceprintIdentifier = pScenario->GetVoiceprintIdentifier();
|
||||
if(pVoiceprintIdentifier)
|
||||
{
|
||||
apt_string_set(&pVerifierHeader->voiceprint_identifier,pVoiceprintIdentifier);
|
||||
mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_VOICEPRINT_IDENTIFIER);
|
||||
}
|
||||
const char* pVerificationMode = pScenario->GetVerificationMode();
|
||||
if(pVerificationMode)
|
||||
{
|
||||
apt_string_set(&pVerifierHeader->verification_mode,pVerificationMode);
|
||||
mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_VERIFICATION_MODE);
|
||||
}
|
||||
}
|
||||
return pMrcpMessage;
|
||||
}
|
||||
|
||||
mrcp_message_t* VerifierSession::CreateEndSessionRequest(mrcp_channel_t* pMrcpChannel)
|
||||
{
|
||||
return CreateMrcpMessage(pMrcpChannel,VERIFIER_END_SESSION);
|
||||
}
|
||||
|
||||
mrcp_message_t* VerifierSession::CreateVerificationRequest(mrcp_channel_t* pMrcpChannel)
|
||||
{
|
||||
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,VERIFIER_VERIFY);
|
||||
if(!pMrcpMessage)
|
||||
return NULL;
|
||||
|
||||
mrcp_verifier_header_t* pVerifierHeader;
|
||||
|
||||
/* get/allocate verifier header */
|
||||
pVerifierHeader = (mrcp_verifier_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
|
||||
if(pVerifierHeader)
|
||||
{
|
||||
pVerifierHeader->no_input_timeout = 5000;
|
||||
mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_NO_INPUT_TIMEOUT);
|
||||
pVerifierHeader->start_input_timers = TRUE;
|
||||
mrcp_resource_header_property_add(pMrcpMessage,VERIFIER_HEADER_START_INPUT_TIMERS);
|
||||
}
|
||||
return pMrcpMessage;
|
||||
}
|
||||
|
||||
FILE* VerifierSession::GetAudioIn(const mpf_codec_descriptor_t* pDescriptor, apr_pool_t* pool) const
|
||||
{
|
||||
const VerifierScenario* pScenario = GetScenario();
|
||||
const char* pVoiceprintIdentifier = pScenario->GetVoiceprintIdentifier();
|
||||
if(!pVoiceprintIdentifier)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Voiceprint Specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* pFileName = apr_psprintf(pool,"%s-%dkHz.pcm",
|
||||
pVoiceprintIdentifier,
|
||||
pDescriptor ? pDescriptor->sampling_rate/1000 : 8);
|
||||
apt_dir_layout_t* pDirLayout = pScenario->GetDirLayout();
|
||||
const char* pFilePath = apt_datadir_filepath_get(pDirLayout,pFileName,pool);
|
||||
if(!pFilePath)
|
||||
return NULL;
|
||||
|
||||
FILE* pFile = fopen(pFilePath,"rb");
|
||||
if(!pFile)
|
||||
{
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Cannot Find [%s]",pFilePath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Set [%s] as Speech Source",pFilePath);
|
||||
return pFile;
|
||||
}
|
||||
Reference in new issue
Block a user