📄 d300.cpp
字号:
* voc_index: 语音索引文件名
* fandle : 用于保存语音文件句柄的指针
* offset : 用于保存语音文件位置的指针
* length : 用于保存语音文件长度的指针
***************************************************************************/
int get_voc_descr(char * voc_index, int * fhandle, int * offset, int *length)
{
int count = 1;
char s_indexname1[40], s_indexname2[40], s_fhandle[10], s_offset[10], s_length[10];
strcpy(s_indexname1, voc_index);
upstring(s_indexname1,s_indexname1);
while (count <= System.VocNumber)
{
//itoa(count,scount,10);
//strcpy(s_indexname2,(const char *) ReadVFIT(scount, "indexname"));
strcpy(s_indexname2, Vfit[count-1].indexname);
upstring(s_indexname2, s_indexname2);
if (strcmp(s_indexname1, s_indexname2)==0) { // voc found!
strcpy(s_fhandle,Vfit[count-1].filehandle);
strcpy(s_offset,Vfit[count-1].io_offset);
strcpy(s_length,Vfit[count-1].io_length);
(*fhandle) = atoi(s_fhandle);
(*offset) = atoi(s_offset);
(*length) = atoi(s_length);
return 1;
}
count ++;
}
return -1;
}
/***************************************************************************
* 函数: int play_voc(int cn, char * voc_index)
*
* Des : 在通道cn上播放语音 voc_index
* cn : 通道号
* voc : 语音索引名
***************************************************************************/
int play_voc(int cn, char * voc_index, bool key_break)
{
int fhandle, io_offset, io_length;
DV_TPT play_tpt;
// Set to terminate play on 1 digit
if (key_break == true)
{
play_tpt.tp_type = IO_EOT;
play_tpt.tp_termno = DX_MAXDTMF;
play_tpt.tp_length = 1;
play_tpt.tp_flags = TF_MAXDTMF;
}
if (get_voc_descr(voc_index, &fhandle, &io_offset, &io_length)==-1) {
SysPrintf("没有找到语音(%s)的数据",voc_index);
return -1;
}
//数据传输表
Channel[cn-1].iott.io_type= IO_DEV | IO_EOT;
Channel[cn-1].iott.io_bufp=0;
Channel[cn-1].iott.io_offset= io_offset;
Channel[cn-1].iott.io_length= io_length;
Channel[cn-1].iott.io_fhandle= fhandle;
//传输参数表
Channel[cn-1].xpb.wFileFormat = FILE_FORMAT_VOX;
Channel[cn-1].xpb.wDataFormat = DATA_FORMAT_DIALOGIC_ADPCM;
Channel[cn-1].xpb.nSamplesPerSec = DRT_8KHZ;
Channel[cn-1].xpb.wBitsPerSample = 4;
dx_clrdigbuf(Channel[cn-1].voc);
//播放
if (dx_playiottdata(Channel[cn-1].voc,&Channel[cn-1].iott,&play_tpt,&(Channel[cn-1].xpb),EV_ASYNC)==-1 ){
SysPrintf("%s: %s in dx_playiottdata()\n",Channel[cn-1].voxname,ATDV_ERRMSGP(Channel[cn-1].voc));
return -1;
}
ChnPrintf(cn,"_STATE", "Playing \'%s\'...",voc_index);
return 1;
}
/*************************************************************************
* FUNC: time_trigger_func(LPVOID pParam)
*
* 说明: 计时器线程,以秒计
*
*
************************************************************************/
UINT time_trigger_func(LPVOID pParam)
{
int cn;
SysPrintf("Time Trigger 启动.");
System.SysThreadNumber ++;
while (SysThread[_timetrigger].keep_running)
{
for (cn = 1; cn<MAXCHAN; cn++)
{
Sleep(0); //相当于 yield()
if (Channel[cn-1].TimeTrigger.IsCounting == true) //处于计时状态
{
if (Channel[cn-1].TimeTrigger.msecond > 0) {
Channel[cn-1].TimeTrigger.msecond--;
}
else
{ //时间到
Channel[cn-1].TimeTrigger.msecond = 0;
Channel[cn-1].TimeTrigger.IsCounting = false;
SysPrintf("(%d)Time Trigger 触发超时事件 !",cn);
put_event_to_board(cn,Channel[cn-1].TimeTrigger.event);
}
}
}
Sleep(1000); //停顿1秒
}
SysPrintf("Time Trigger 退出!");
--System.SysThreadNumber;
if (System.SysThreadNumber == 0) {
System.AllThreadClosed.SetEvent();
}
return 1;
} //end of time_trigger_func()
/*************************************************************************
* FUNC: start_time_trigger()
*
* 说明: 启动计时器线程
*
*
************************************************************************/
void start_time_trigger()
{
SysThread[_timetrigger].pThread = ::AfxBeginThread(time_trigger_func, NULL);
return;
}
/*************************************************************************
* 函数: stop_timing(int cn)
*
* 功能: 终止通道的超时计算
* 参数: cn : 通道号
*
************************************************************************/
int stop_timing(int cn)
{
Channel[cn-1].TimeTrigger.event = _nodefine;
Channel[cn-1].TimeTrigger.msecond = 0;
Channel[cn-1].TimeTrigger.IsCounting = false;
return 0;
}
/*************************************************************************
* 函数: start_timing(int cn, int second, STATE evt_put)
*
* 功能: 启动通道的超时计算
* 参数: cn : 通道号
* second : 时限(以秒为单位)
* evt_put : 超时后通道上写的事件
*
************************************************************************/
int start_timing(int cn, int second, STATE evt_put)
{
Channel[cn-1].TimeTrigger.event = evt_put;
Channel[cn-1].TimeTrigger.msecond = second;
Channel[cn-1].TimeTrigger.IsCounting = true;
return 0;
}
/*************************************************************************
* 函数: int set_singleinput_io(int cn, type_SGIPT_IO * io_param)
*
* 功能: 设置 singleinput thread 的切换参数表
* 参数:
* cn : 通道号
* io_param : 切换参数表
*
************************************************************************/
int set_singleinput_io(int cn, type_SGIPT_IO * io_param)
{
int i = 0;
// 设置IO参数表
Channel[cn-1].SingleInput.cur_st = sgipt_idle;
Channel[cn-1].SingleInput.io.num = io_param->num;
//Channel[cn-1].SingleInput.io.errortimes = io_param->errortimes;
strcpy(Channel[cn-1].SingleInput.io.buffer,io_param->buffer);
// 复制"值--向"表
while (i < io_param->num)
{
Channel[cn-1].SingleInput.io.keytable[i].key = io_param->keytable[i].key;
Channel[cn-1].SingleInput.io.keytable[i].goto_thread = io_param->keytable[i].goto_thread;
Channel[cn-1].SingleInput.io.keytable[i].goto_state = io_param->keytable[i].goto_state;
i++;
}
return 1;
}
/*************************************************************************
* 函数: int adjust_singleinput_io(int cn)
*
* 功能: 修正 singleinput thread 的切换参数表
* 参数:
* cn : 通道号
*
*
************************************************************************/
int adjust_singleinput_io(int cn)
{
static int i = 2; //返回上一级菜单查询
char Cur_UserOp[40];
strcpy(Cur_UserOp,Channel[cn-1].Main.UserOp);
//欠费查询
if (strcmp(Cur_UserOp,Query_QF)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = vm_1_play;
return 0;
}
//单机单月
if (strcmp(Cur_UserOp,Query_DJDY)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = cmd0_hf;
return 0;
}
//托收查询
if (strcmp(Cur_UserOp,Query_TSHOU)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = cmd0_hf;
return 0;
}
//168详单
if (strcmp(Cur_UserOp,Query_168XD)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = cmd0_xd;
return 0;
}
//本地网详单
if (strcmp(Cur_UserOp,Query_BDWXD)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = cmd0_xd;
return 0;
}
//长途详单
if (strcmp(Cur_UserOp,Query_CTXD)==0) {
Channel[cn-1].SingleInput.io.keytable[i].goto_state = cmd0_xd;
return 0;
}
return 0;
}
/*************************************************************************
* 函数: int switch_thread(int cn, TRHEAD next_thread, STATE next_state)
*
* 功能: 切换线程
* 参数:
* cn : 通道号
* next_thread : 下一线程
* next_state : 下一状态
*
************************************************************************/
int switch_thread(int cn, THREAD next_thread, STATE next_state)
{
int i = 0;
// 设置当前线程状态
switch (Channel[cn-1].thread_id){
case _main:
Channel[cn-1].Main.cur_st = main_sleep;
break;
case _singleinput:
Channel[cn-1].SingleInput.cur_st = sgipt_idle;
break;
case _monthinput:
Channel[cn-1].MonthInput.cur_st = mth_idle;
break;
case _multiplay:
Channel[cn-1].MultiPlay.cur_st = mply_idle;
break;
case _timeout:
Channel[cn-1].TimeOut.cur_st = tm_idle;
break;
default:
WinPrintf("switch_thread():error thread_id = %d",Channel[cn-1].thread_id);
}
// 设置下一当前线程
Channel[cn-1].thread_id = next_thread;
// 设置下一状态
put_event_to_board(cn,next_state);
//ChnPrintf(cn,"_STATE", "已切换至线程%d",next_thread);
return 1;
}
/*************************************************************************
* FUNC: int post_read_command_to_board(int cn, int number=1)
*
* 说明: 启动读键命令
* 参数: cn = 通道号,number = 读键个数(默认参数,不指定则
* 等于1。
*
************************************************************************/
int post_read_command_to_board(int cn, int number)
{
int mode = EV_ASYNC; //异步读
if (number < 1) return 0;
//设置终止参数表 dig_tpt
// 1.读键个数 = number
Channel[cn-1].dig_tpt[0].tp_type = IO_CONT;
Channel[cn-1].dig_tpt[0].tp_termno = DX_MAXDTMF;
Channel[cn-1].dig_tpt[0].tp_length = number;
Channel[cn-1].dig_tpt[0].tp_flags = TF_MAXDTMF; // define in ATDX_TERMMSK()
if ( number > 1){
// 2.总持续时间 = number * MaxWaitKeyTime
Channel[cn-1].dig_tpt[1].tp_type = IO_CONT;
Channel[cn-1].dig_tpt[1].tp_termno = DX_MAXTIME;
Channel[cn-1].dig_tpt[1].tp_length = number * MaxWaitKeyTime *100; //(0.1 秒为单位)
Channel[cn-1].dig_tpt[1].tp_flags = TM_MAXTIME;
// 3.键与键之间的延续时间 = MaxWaitKeyTime
Channel[cn-1].dig_tpt[2].tp_type = IO_EOT;
Channel[cn-1].dig_tpt[2].tp_termno = DX_IDDTIME;
Channel[cn-1].dig_tpt[2].tp_length = number * MaxWaitKeyTime * 100;
Channel[cn-1].dig_tpt[2].tp_flags = TM_IDDTIME;
}
else{
// 2.总持续时间 = number * MaxWaitKeyTime
Channel[cn-1].dig_tpt[1].tp_type = IO_EOT;
Channel[cn-1].dig_tpt[1].tp_termno = DX_MAXTIME;
Channel[cn-1].dig_tpt[1].tp_length = number * MaxWaitKeyTime * 100;
Channel[cn-1].dig_tpt[1].tp_flags = TM_MAXTIME;
}
//if (dx_clrdigbuf(Channel[cn-1].voc) == -1) {
// WinPrintf("post_read_command_to_board():错误:%s!", ATDV_ERRMSGP(Channel[cn-1].voc));
// return -1;
//}
if(dx_getdig(Channel[cn-1].voc, Channel[cn-1].dig_tpt, &(Channel[cn-1].digp),mode) == -1)
{
WinPrintf("post_read_command_to_board():错误:%s!", ATDV_ERRMSGP(Channel[cn-1].voc));
return -1;
}
return 1;
}
/*************************************************************************
* FUNC: int read_the_key(int cn)
*
* 说明: 读接收到的键
* 参数: cn = 通道号,
*
************************************************************************/
int read_the_key(int cn)
{
int i= 0;
while (Channel[cn-1].digp.dg_value[i]!='\0') //读到
{
Channel[cn-1].lastkey = Channel[cn-1].digp.dg_value[i];
Channel[cn-1].keybuffer[Channel[cn-1].keynumber++] = Channel[cn-1].digp.dg_value[i];
Channel[cn-1].keybuffer[Channel[cn-1].keynumber] = '\0';
i++;
ChnPrintf(cn,"_USER","用户按键={%s}",Channel[cn-1].keybuffer);
}
//读完后清空数字缓冲区
Channel[cn-1].digp.dg_value[0]='\0'; //人工清除
return i;
}
/*************************************************************************
* FUNC: int end_this_read(int cn)
*
* 说明: 结束读键命令,清空读键缓冲区
* 参数: cn = 通道号
*
************************************************************************/
void end_this_read(int cn)
{
dx_stopch(Channel[cn-1].voc, EV_ASYNC);
dx_clrdigbuf(Channel[cn-1].voc);
Channel[cn-1].keynumber = 0;
Channel[cn-1].lastkey = '\0';
Channel[cn-1].keybuffer[0] = '\0';
}
/*************************************************************************
* FUNC: int verify_the_key(int cn, THREAD * go_thread, STATE * go_state)
*
* 说明: 根据io参数表校验读键
* 参数: cn = 通道号
* go_thread = 键值有效的下一线程
* go_state = 键值有效的下一状态
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -