📄 d300.cpp.demo
字号:
#include "stdafx.h" //这个头文件一定要加,不然编译通不过
#include "d300.h"
#include "myvc.h"
char *voxchannels[] = {
"dxxxB1C1" , "dxxxB1C2" , "dxxxB1C3" , "dxxxB1C4",
"dxxxB2C1" , "dxxxB2C2" , "dxxxB2C3" , "dxxxB2C4",
"dxxxB3C1" , "dxxxB3C2" , "dxxxB3C3" , "dxxxB3C4",
"dxxxB4C1" , "dxxxB4C2" , "dxxxB4C3" , "dxxxB4C4",
"dxxxB5C1" , "dxxxB5C2" , "dxxxB5C3" , "dxxxB5C4",
"dxxxB6C1" , "dxxxB6C2" , "dxxxB6C3" , "dxxxB6C4",
"dxxxB7C1" , "dxxxB7C2" , "dxxxB7C3" , "dxxxB7C4",
"dxxxB8C1" , "dxxxB8C2" ,
NULL,
};
char *dtichannels[] = {
"dtiB1T1" , "dtiB1T2" , "dtiB1T3" , "dtiB1T4",
"dtiB1T5" , "dtiB1T6" , "dtiB1T7" , "dtiB1T8",
"dtiB1T9" , "dtiB1T10", "dtiB1T11", "dtiB1T12",
"dtiB1T13", "dtiB1T14", "dtiB1T15", "dtiB1T16",
"dtiB1T17", "dtiB1T18", "dtiB1T19", "dtiB1T20",
"dtiB1T21", "dtiB1T22", "dtiB1T23", "dtiB1T24",
"dtiB1T25", "dtiB1T26", "dtiB1T27", "dtiB1T28",
"dtiB1T29", "dtiB1T30",
NULL,
};
CHANNEL dev[MAXCHAN];
DV_TPT tpt[3];
DV_DIGIT digp[256];
int promptfh;
int EventType;
/*************************************************************************
* 函数 : sysinit()
* 描叙 : 打开语音卡
*
* 参数 : 无
* 说明 : 根据semaphore的配置,打开查询程序的全部端口
* 返回 : 打开并占用的端口数量,<=0 表示打开失败.
*************************************************************************/
void sysinit(void)
{
int mode;
int i;
/* Set the Device to Polled Mode 设置语音卡为轮询问模式*/
mode = SR_POLLMODE;
if (sr_setparm(SRL_DEVICE,SR_MODEID,&mode )==-1) { //sr_setparm( ) function allows the application to set
//the value of an SRL(Standard Runtime Library) parameter
printf("sr_setparm()\n");
exit(0);
}
promptfh=dx_fileopen("sample.vox",O_RDONLY|O_BINARY);
if(promptfh<=0){
printf("File SAMPLE.VOX not found, please copy it to the current directory.\n");
exit(0);
}
for (i = 0; i < MAXCHAN; i++) {
//打开语音卡端口
strcpy(dev[i].voxname,voxchannels[i]);
if ((dev[i].vox = dx_open(dev[i].voxname, 0)) == -1) {
printf("%s: Error opening this channel\n",dev[i].voxname);
exit(1);
}
//打开中继卡端口
strcpy(dev[i].dtiname,dtichannels[i]);
if ((dev[i].dti = dt_open(dev[i].dtiname, 0)) == -1) {
printf("%s: Error opening this channel\n",dev[i].dtiname);
exit(1);
}
//
//连接语音卡和中继卡两种设备。这里涉及到 SCBus,SCBus是Dialogic公司的一种硬件
//技术,用于连接不同的DEVICE. D300/SC-E1卡其实就是用SCBus连接一个30路语音卡
//和一个30口中继卡为一体的产品。
// nr_nr_scunroute()函数的作用在于断开 dit 和 voice之间的连接。
if(nr_scunroute(dev[i].dti,SC_DTI,dev[i].vox,SC_VOX,SC_FULLDUP)==-1){
printf("%s <=== UnRoute Failed ===> %s\n",dev[i].voxname,dev[i].dtiname);
exit(1);
}
//重建 dti 和voice之间的连接。(全双工连接)
if(nr_scroute(dev[i].dti,SC_DTI,dev[i].vox,SC_VOX,SC_FULLDUP)==-1){
printf("%s <=== Route Failed ===> %s\n",dev[i].voxname,dev[i].dtiname);
exit(1);
}
//语音卡要监听来自交换机的前向信号( R2MF, forward signal),必须调用 r2_createfsig
//建立一个模板(template),指定监听哪些signal, dx_deltons()则是清除这个template.
if(dx_deltones(dev[i].vox)==-1){
printf("%s: dx_deltones()\n",dev[i].voxname);
exit(1);
}
//重建template,指定端口监听所有的(forward signal)
if(r2_creatfsig(dev[i].vox,R2_ALLFSIG)==-1){
printf("%s: r2_creatfsig()\n",dev[i].voxname);
exit(1);
}
//数字设备上有一个传输信号字节Bitmask,用于表示事件,其bitmask有如下
/* DTB_AON - "A" signaling bit on
DTB_AOFF - "A" signaling bit off
DTB_BON - "B" signaling bit on
DTB_BOFF - "B" signaling bit off
DTB_CON - "C" signaling bit on (E-1 only)
DTB_COFF - "C" signaling bit off (E-1 only)
DTB_DON - "D" signaling bit on (E-1 only)
DTB_DOFF - "D" signaling bit off (E-1 only) */
if(dt_settssigsim(dev[i].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON)==-1){
printf("dt_settssig() in dt_onhook(1)\n");
exit(1);
}
chan_init(i);
/*chan_init(){
if(DEBUG) printf("%s: In chan_init()\n",dev[i].voxname);
strcpy(dev[i].dnis,"");
strcpy(dev[i].ani,"");
dev[i].number=0;
dev[i].state=ST_SZ_ACK;
dt_settssigsim(dev[i].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON);
}
*/
//接收信号事件,对于SC设备 AON和AOFF同时要设置。
if(dt_setevtmsk(dev[i].dti,DTG_SIGEVT,DTMM_AON|DTMM_AOFF,DTA_SETMSK)==-1){
printf("%s: dt_setevtmsk()\n",dev[i].dtiname);
exit(1);
}
printf(".");
}
printf("\nAll Channels opened, dial in now.\n");
}
/***************************************************************************
* Name: int dx_intro( channum )
* Des: Set up play_iott and play_tpt's and Initiate the Play-Back and update
* the child window.
* Input : int channel number;
* Output: Starts the play-back
***************************************************************************/
int dt_playf(int i)
{
if(DEBUG) printf("%s: In dt_playf()\n",dev[i].voxname);
memset(play_tpt,0,sizeof(play_tpt));
// Terminate Play on Receiving any DTMF tone 终止条件1:用户按任何键。
play_tpt[0].tp_type = IO_CONT;
play_tpt[0].tp_termno = DX_MAXDTMF;
play_tpt[0].tp_length = 1;
play_tpt[0].tp_flags = TF_MAXDTMF;
// Terminate on MAXTIME
play_tpt[1].tp_type = IO_EOT;
play_tpt[1].tp_termno = DX_MAXTIME;
play_tpt[1].tp_length = PLAY_TIME * 10;
play_tpt[1].tp_flags = TF_MAXTIME;
play_iott.io_type=IO_DEV|IO_LINK;
play_iott.io_bufp=0;
play_iott.io_offset=0;
play_iott.io_length=-1;
play_iott.io_fhandle=promptfh;
play_iott.io_nextp=&play_iott;
xpb.wFileFormat = FILE_FORMAT_VOX;
xpb.wDataFormat = DATA_FORMAT_DIALOGIC_ADPCM;
xpb.nSamplesPerSec = DRT_8KHZ;
xpb.wBitsPerSample = 4;
dx_clrdigbuf(dev[i].vox);
/* Play VOX File on D/4x Channel, Normal Play Back */
if (dx_playiottdata(dev[i].vox,&play_iott,play_tpt,&xpb,/*PM_TONE|*/EV_ASYNC)==-1 ){
printf("%s: %s in dx_play()\n",dev[i].voxname,ATDV_ERRMSGP(dev[i].vox));
return -1;
}
printf("%s: playing...\n",dev[i].voxname);
return 0;
}
/******************************************************************************
* Name: check_event()
* Input: int channel number
* int voice/msi events
* Des: It checks the current state of a channel, look up in the state
* for the next state of the channel depanding on the event received
* sets the next state and initiates the apprpriate func.
*
*
*******************************************************************************/
int check_event(int channel, int event)
{
int i;
int (*func_ptr)(int);
//首先检测挂机事件(Hangup detection is the first priority )
if((EventType==DTEV_SIG)&&(event==DTMM_AON)) {
// Abit跳1,表明有一方挂断,如果当前状态是ST_SZ_ACK,表明是语音卡主动挂机
// 通话结束工作留给交换机去完成,语音卡回到初始状态。
// 如果是交换机先挂,则要返回一个用户断也挂的backward signal,然后才能回到
// 初始状态,这个工作则是由 dt_fwaon()函数完成的。
if(dev[channel].state==ST_SZ_ACK) chan_init(channel);
else dt_fwaon(channel);
return 0;
}
for (i=0; i< TABLE_SIZE; i++)
if((dev[channel].state==table[i].current_state) &&
(table[i].event==event)){
func_ptr = table[i].funcptr;
if(DEBUG) printf("%s: Current State =%d, Event Function Number is (%d)\n",dev[channel].voxname,dev[channel].state,i);
dev[channel].state = table[i].next_state;
return (*func_ptr)(channel);
break;
}
return -1;
}
/****************************************************************************
* Name: process_event
* Input: int channel number
* output: returns a voice event
* Des: It retreives voice events on a channel by calling sr_getevttype()
* sr_getevtdatap() and returns it to the wait_event()
*
*
*****************************************************************************/
int process_event(int channel)
{
int index;
int *datap;
long term;
DX_CST *cstp;
int chfd;
int cnt, numdigs;
//EventType = sr_getevttype(dev[channel].vox);
EventType = sr_getevttype(); //原来的语句
switch(EventType){
case DTEV_SIG: //DTI 上的信号事件,datap是事件的bitmask(ABCD);
datap=(int*)sr_getevtdatap();
for(index=0;index<4;index++){
switch (*datap&(0x1111<<index)){
case DTMM_AON:
//if(DEBUG) printf("%s: EVENT DATA: DTMM_AON\n",dev[channel].voxname);
return DTMM_AON;
break;
case DTMM_AOFF:
if(DEBUG) printf("%s: EVENT DATA: DTMM_AOFF\n",dev[channel].voxname);
return DTMM_AOFF;
break;
case DTMM_BON:
if(DEBUG) printf("%s: EVENT DATA: DTMM_BON\n",dev[channel].voxname);
return DTMM_BON;
break;
case DTMM_BOFF:
if(DEBUG) printf("%s: EVENT DATA: DTMM_BOFF\n",dev[channel].voxname);
return DTMM_BOFF;
break;
case DTMM_CON:
if(DEBUG) printf("%s: EVENT DATA: DTMM_CON\n",dev[channel].voxname);
return DTMM_CON;
break;
case DTMM_COFF:
if(DEBUG) printf("%s: EVENT DATA: DTMM_COFF\n",dev[channel].voxname);
return DTMM_COFF;
break;
case DTMM_DON:
if(DEBUG) printf("%s: EVENT DATA: DTMM_DON\n",dev[channel].voxname);
return DTMM_DON;
break;
case DTMM_DOFF:
if(DEBUG) printf("%s: EVENT DATA: DTMM_DOFF\n",dev[channel].voxname);
return DTMM_DOFF;
break;
}
}
break;
case TDX_CST: //Vocie上的状态事件
if(DEBUG) printf("%s: EVENT TYPE: TDX_CST\n",dev[channel].voxname);
cstp=(DX_CST*)sr_getevtdatap();
switch (cstp->cst_event){
case DE_TONEON:
//if(DEBUG) printf("%s: EVENT DATA: DE_TONEON\n",dev[channel].voxname);
return DE_TONEON;
break;
case DE_TONEOFF:
//if(DEBUG) printf("%s: EVENT DATA: DE_TONEOFF\n",dev[channel].voxname);
return -1; //
break;
}
case TDX_GETDIG:
// ###
printf("通道%s读键完\n",dev[channel].voxname);
numdigs = strlen(digp[channel].dg_value);
for(cnt=0; cnt < numdigs; cnt++) {
printf("\nDigit received = %c, digit type = %d", digp[channel].dg_value[cnt], digp[channel].dg_type[cnt]);
}
return TM_EOD;
break;
case TDX_PLAY: /* Play ENDS*/
//if(DEBUG)
//#define TM_NORMTERM 0x00000 /* Normal Termination */
//#define TM_MAXDTMF 0x00001 /* Max Number of Digits Recd */
//#define TM_MAXSIL 0x00002 /* Max Silence */
//#define TM_MAXNOSIL 0x00004 /* Max Non-Silence */
//#define TM_LCOFF 0x00008 /* Loop Current Off */
//#define TM_IDDTIME 0x00010 /* Inter Digit Delay */
//#define TM_MAXTIME 0x00020 /* Max Function Time Exceeded */
//#define TM_DIGIT 0x00040 /* Digit Mask or Digit Type Term. */
//#define TM_PATTERN 0x00080 /* Pattern Match Silence Off */
//#define TM_USRSTOP 0x00100 /* Function Stopped by User */
//#define TM_EOD 0x00200 /* End of Data Reached on Playback */
//#define TM_TONE 0x02000 /* Tone On/Off Termination */
//#define TM_BARGEIN 0x08000 /* Play terminated due to Barge-in */
//#define TM_ERROR 0x80000 /* I/O Device Error */
printf("%s: EVENT TYPE: TDX_PLAY\n",dev[channel].voxname);
term=ATDX_TERMMSK(dev[channel].vox); //检测播报的终止情况。
if(term & TM_EOD) {
printf("%s: Play ended by 全部拨完TM_EOD\n",dev[channel].voxname);
}
if(term & TM_MAXTIME){ //超时
printf("%s: Play ended by 超出时间TM_MAXTIME\n",dev[channel].voxname);
}
if (term & TM_USRSTOP){
printf("%s: Play ended by 用户挂机终止(tm_usrstop)\n",dev[channel].voxname);
//按键终止语音的情况下开始读键
if (strcmp(dev[channel].dnis,"177")==0) {
ReadUserKey(channel);
}
}
if (term & TM_MAXDTMF){
printf("%s: Play ended by 用户按键终止(tM_maxdtmf)\n",dev[channel].voxname);
//按键终止语音的情况下开始读键
if (strcmp(dev[channel].dnis,"177")==0) {
ReadUserKey(channel);
}
}
//return TM_EOD;
break;
case TDX_PLAYTONE:
//if(DEBUG) printf("%s: EVENT DATA: TDX_PLAYTONE\n",dev[channel].voxname);
return TM_TONE;
break;
default:
if(DEBUG) printf("%s: EVENT TYPE AND DATA: 0X%X UNANALYSED\n",dev[channel].voxname,EventType);
return EventType;
break;
} // end switch
}
/*************************************************************************
* NAME: wait_event()
* Input: None
* Des: It blocks at sr_waitevt() and wait for events, once the event is
* received, it find out the device and channel number and calls
* process_events() for voice and ms_process_event() for msi events.
* After getting an event, it calls check_events() to initiate the
* appropriate function.
**************************************************************************/
void wait_event()
{
int channel;
int chdev;
int event;
char ch;
while ( 1 ) {
if(_kbhit()){
ch=_getch();
if(ch==27) break;
}
/* Wait for Completion of an Event */
if(sr_waitevt(-1)==-1){
continue;
}
//printf("----------------- Event comes. ---------------\n");
// Get the channel number from which the event was received.
channel = 0;
chdev = sr_getevtdev();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -