freeswitch/libs/unimrcp/platforms/umc/src/setparamsession.cpp

390 lines
12 KiB
C++

/*
* 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: setparamsession.cpp 1474 2010-02-07 20:51:47Z achaloyan $
*/
#include "setparamsession.h"
#include "setparamscenario.h"
#include "mrcp_message.h"
#include "mrcp_generic_header.h"
#include "mrcp_recog_header.h"
#include "mrcp_recog_resource.h"
#include "apt_log.h"
struct RecogChannel
{
/** MRCP control channel */
mrcp_channel_t* m_pMrcpChannel;
};
SetParamSession::SetParamSession(const SetParamScenario* pScenario) :
UmcSession(pScenario),
m_pRecogChannel(NULL),
m_RequestQueue(NULL),
m_CurrentRequest(0)
{
}
SetParamSession::~SetParamSession()
{
}
bool SetParamSession::Start()
{
/* create channel and associate all the required data */
m_pRecogChannel = CreateRecogChannel();
if(!m_pRecogChannel)
return false;
/* add channel to session (send asynchronous request) */
if(!AddMrcpChannel(m_pRecogChannel->m_pMrcpChannel))
{
delete m_pRecogChannel;
m_pRecogChannel = NULL;
return false;
}
return true;
}
bool SetParamSession::OnSessionTerminate(mrcp_sig_status_code_e status)
{
if(m_pRecogChannel)
{
delete m_pRecogChannel;
m_pRecogChannel = NULL;
}
return UmcSession::OnSessionTerminate(status);
}
static apt_bool_t ReadStream(mpf_audio_stream_t* pStream, mpf_frame_t* pFrame)
{
return TRUE;
}
RecogChannel* SetParamSession::CreateRecogChannel()
{
mrcp_channel_t* pChannel;
mpf_termination_t* pTermination;
mpf_stream_capabilities_t* pCapabilities;
apr_pool_t* pool = GetSessionPool();
/* create channel */
RecogChannel *pRecogChannel = new RecogChannel;
pRecogChannel->m_pMrcpChannel = NULL;
/* 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 */
pRecogChannel); /* object to associate */
pChannel = CreateMrcpChannel(
MRCP_RECOGNIZER_RESOURCE, /* MRCP resource identifier */
pTermination, /* media termination, used to terminate audio stream */
NULL, /* RTP descriptor, used to create RTP termination (NULL by default) */
pRecogChannel); /* object to associate */
if(!pChannel)
{
delete pRecogChannel;
return NULL;
}
pRecogChannel->m_pMrcpChannel = pChannel;
return pRecogChannel;
}
bool SetParamSession::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();
}
if(!CreateRequestQueue(pMrcpChannel))
{
return Terminate();
}
return ProcessNextRequest(pMrcpChannel);
}
bool SetParamSession::OnMessageReceive(mrcp_channel_t* pMrcpChannel, mrcp_message_t* pMrcpMessage)
{
if(!UmcSession::OnMessageReceive(pMrcpChannel,pMrcpMessage))
return false;
if(pMrcpMessage->start_line.message_type == MRCP_MESSAGE_TYPE_RESPONSE)
{
/* received MRCP response */
if(pMrcpMessage->start_line.method_id == RECOGNIZER_SET_PARAMS || pMrcpMessage->start_line.method_id == RECOGNIZER_GET_PARAMS)
{
/* received the response */
if(pMrcpMessage->start_line.request_state == MRCP_REQUEST_STATE_COMPLETE)
{
m_CurrentRequest++;
ProcessNextRequest(pMrcpChannel);
}
else
{
/* received unexpected response, terminate the session */
Terminate();
}
}
else
{
/* received unexpected response */
Terminate();
}
}
return true;
}
bool SetParamSession::ProcessNextRequest(mrcp_channel_t* pMrcpChannel)
{
if(m_CurrentRequest >= m_RequestQueue->nelts)
{
return Terminate();
}
mrcp_message_t* pMrcpMessage = APR_ARRAY_IDX(m_RequestQueue,m_CurrentRequest,mrcp_message_t*);
if(!pMrcpMessage)
{
return Terminate();
}
return SendMrcpRequest(pMrcpChannel,pMrcpMessage);
}
bool SetParamSession::CreateRequestQueue(mrcp_channel_t* pMrcpChannel)
{
m_CurrentRequest = 0;
m_RequestQueue = apr_array_make(GetSessionPool(),5,sizeof(mrcp_message_t*));
mrcp_message_t* pMrcpMessage;
pMrcpMessage = CreateSetParams1(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
pMrcpMessage = CreateGetParams1(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
pMrcpMessage = CreateSetParams2(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
pMrcpMessage = CreateGetParams2(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
pMrcpMessage = CreateSetParams3(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
pMrcpMessage = CreateGetParams3(pMrcpChannel);
if(pMrcpMessage)
*(mrcp_message_t**)apr_array_push(m_RequestQueue) = pMrcpMessage;
return true;
}
mrcp_message_t* SetParamSession::CreateSetParams1(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_SET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_recog_header_t* pRecogHeader;
/* get/allocate recog header */
pRecogHeader = (mrcp_recog_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
if(pRecogHeader)
{
/* set recog header fields */
pRecogHeader->confidence_threshold = 0.4f;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD);
pRecogHeader->sensitivity_level = 0.531f;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_SENSITIVITY_LEVEL);
pRecogHeader->speed_vs_accuracy = 0.5f;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEED_VS_ACCURACY);
pRecogHeader->n_best_list_length = 5;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_N_BEST_LIST_LENGTH);
pRecogHeader->no_input_timeout = 5000;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_NO_INPUT_TIMEOUT);
}
return pMrcpMessage;
}
mrcp_message_t* SetParamSession::CreateGetParams1(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_GET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_recog_header_t* pRecogHeader;
/* get/allocate recog header */
pRecogHeader = (mrcp_recog_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
if(pRecogHeader)
{
/* set recog header fields */
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_CONFIDENCE_THRESHOLD);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_SENSITIVITY_LEVEL);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEED_VS_ACCURACY);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_N_BEST_LIST_LENGTH);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_NO_INPUT_TIMEOUT);
}
return pMrcpMessage;
}
mrcp_message_t* SetParamSession::CreateSetParams2(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_SET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_recog_header_t* pRecogHeader;
/* get/allocate recog header */
pRecogHeader = (mrcp_recog_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
if(pRecogHeader)
{
/* set recog header fields */
pRecogHeader->recognition_timeout = 5000;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT);
pRecogHeader->speech_complete_timeout = 1000;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEECH_COMPLETE_TIMEOUT);
pRecogHeader->speech_incomplete_timeout = 2000;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEECH_INCOMPLETE_TIMEOUT);
pRecogHeader->dtmf_interdigit_timeout = 3000;
mrcp_resource_header_property_add(pMrcpMessage,RECOGNIZER_HEADER_DTMF_INTERDIGIT_TIMEOUT);
}
return pMrcpMessage;
}
mrcp_message_t* SetParamSession::CreateGetParams2(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_GET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_recog_header_t* pRecogHeader;
/* get/allocate recog header */
pRecogHeader = (mrcp_recog_header_t*) mrcp_resource_header_prepare(pMrcpMessage);
if(pRecogHeader)
{
/* set recog header fields */
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_RECOGNITION_TIMEOUT);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEECH_COMPLETE_TIMEOUT);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_SPEECH_INCOMPLETE_TIMEOUT);
mrcp_resource_header_name_property_add(pMrcpMessage,RECOGNIZER_HEADER_DTMF_INTERDIGIT_TIMEOUT);
}
return pMrcpMessage;
}
mrcp_message_t* SetParamSession::CreateSetParams3(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_SET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_generic_header_t* pGenericHeader;
/* get/allocate generic header */
pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pMrcpMessage);
if(pGenericHeader)
{
apr_pool_t* pool = GetSessionPool();
/* set generic header fields */
apt_pair_arr_t* pVSP = apt_pair_array_create(3,pool);
if(pVSP)
{
apt_str_t name;
apt_str_t value;
apt_string_set(&name,"confidencelevel");
apt_string_set(&value,"500");
apt_pair_array_append(pVSP,&name,&value,pool);
apt_string_set(&name,"sensitivity");
apt_string_set(&value,"0.500");
apt_pair_array_append(pVSP,&name,&value,pool);
apt_string_set(&name,"speedvsaccuracy");
apt_string_set(&value,"0.789");
apt_pair_array_append(pVSP,&name,&value,pool);
apt_string_set(&name,"timeout");
apt_string_set(&value,"1000");
apt_pair_array_append(pVSP,&name,&value,pool);
apt_string_set(&name,"swirec_application_name");
apt_string_set(&value,"UniMRCP");
apt_pair_array_append(pVSP,&name,&value,pool);
apt_string_set(&name,"swirec_phoneme_lookahead_beam");
apt_string_set(&value,"-50");
apt_pair_array_append(pVSP,&name,&value,pool);
pGenericHeader->vendor_specific_params = pVSP;
mrcp_generic_header_property_add(pMrcpMessage,GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS);
}
}
return pMrcpMessage;
}
mrcp_message_t* SetParamSession::CreateGetParams3(mrcp_channel_t* pMrcpChannel)
{
mrcp_message_t* pMrcpMessage = CreateMrcpMessage(pMrcpChannel,RECOGNIZER_GET_PARAMS);
if(!pMrcpMessage)
return NULL;
mrcp_generic_header_t* pGenericHeader;
/* get/allocate generic header */
pGenericHeader = (mrcp_generic_header_t*) mrcp_generic_header_prepare(pMrcpMessage);
if(pGenericHeader)
{
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_ACCEPT_CHARSET);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_CACHE_CONTROL);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_LOGGING_TAG);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_VENDOR_SPECIFIC_PARAMS);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_FETCH_TIMEOUT);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_SET_COOKIE);
mrcp_generic_header_name_property_add(pMrcpMessage,GENERIC_HEADER_SET_COOKIE2);
}
return pMrcpMessage;
}