C#控制语音卡实现呼叫、录音以及来电弹屏

最近,正在忙基于三汇语音卡的呼叫中心的项目,真的好迷糊啊!公司在呼叫中心这方面的研发是空白,所有的资料都得从零开始收集,分析,上网查找一些前辈们的技术资料,在这里备个份,好好学习一下!

---------------------------------------------------------------------------------------------------------------------

随着语音技术的不断发展,语音卡在通信行业应用非常广泛。本节通过几个典型实例介绍语音卡程序的开发。

说明-1
实例428 语音卡电话呼叫系统
实例说明
随着科学技术的不断发展,语音卡被广泛地应用于商业软件中。本例实现了利用语音卡实现电话呼叫的功能。实例运行结果如图13.12所示。

说明-2
技术要点
本例采用东进公司开发的8路模拟语音卡,该卡采用灵活的模式化设计,可按需配置外线、内线两种模块。该语音卡可实现坐席、会议、FSK数据收发、语音合成等多种功能,并提供SDK开发工具包。
在安装完驱动程序后,相应的动态链接库(NewSig.dll和Tc08a32.dll文件)会复制到Windows的系统目录下。在语音卡的开发过程中,主要通过调用NewSig.dll和Tc08a32.dll来实现相应的功能。下面介绍这两个动态库中的主要使用函数。
(1)LoadDRV函数
该函数用于加载动态链接库。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern long LoadDRV();
返回值:返回值为0表示成功;−1表示打开设备驱动程序错误。−2表示在读取TC08A-V.INI文件时发生错误;−3表示INI文件的设置与实际的硬件不一致时发生错误。
(2)FreeDRV函数
该函数用于关闭驱动程序。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern long EnableCard(short wusedCh, short wFileBufLen);
(3)EnableCard函数
该函数用于初始化语音卡硬件,并为每个通道分配语音缓冲区。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern long EnableCard(short wusedCh, short wFileBufLen);
参数说明如下。
l     wUsedCh:标识通道数量。
l     WFileBufLen:标识分配的缓冲区大小。
(4)CheckValidCh函数
该函数检测在当前机器内可用的通道总数。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern short CheckValidCh();
l     返回值:通道总数量。
(5)CheckChType函数
该函数用于测试某个通道的类型。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern short CheckChType(short wChnlNo);
参数说明如下。
l     wChnlNo:标识通道号。
l     返回值:为0表示内线;为1表示外线;为2表示悬空。
(6)PUSH_PLAY函数
该函数用于维持文件录放音的持续进行,需在处理函数的大循环中调用。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern void PUSH_PLAY();
(7)SetBusyPara函数
该函数用于设置要检测的挂机忙音的参数。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern void SetBusyPara(short BusyLen);
参数说明:
l     BusyLen:标识忙音的时间长度,单位为毫秒。
(8)RingDetect函数
该函数用于测试外线是否振铃或内线是否提机。语法如下:
       [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern bool RingDetect(short wChnlNo);
参数说明如下。
l     wChnlNo:标识通道号。
返回值:如果为1,对于外线表示有振铃信息;对于内线,表示提机。如果为0,对于外线,表示无振铃信息;对于内线,表示挂机。
(9)OffHook函数
该函数用于外线提机。对于内线,不起作用。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern void OffHook(short wChnlNo);
参数说明如下。
l     wChnlNo:标识外线通道。
(10)HangUp函数
该函数用于外线挂机。对于内线,不起作用。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern void HangUp(short wChnlNo);
参数说明如下。
l     wChnlNo:标识外线通道。
(11)Sig_Init函数
该函数用于完成信号音检测的初始化工作。语法如下:
        [DllImport("NewSig.dll", CharSet = CharSet.Auto)]
        public static extern void Sig_Init(int Times);
参数说明如下。
l     wPara:缺省值为0,不起作用。
(12)Sig_CheckBusy函数
清空忙音检测的缓冲区以及内部计数。当检测对方挂机的忙音后,必须调用本函数。语法如下:
        [DllImport("NewSig.DLL", CharSet = CharSet.Auto)]
        public static extern void Sig_ResetCheck(short wChlNo);
参数说明如下。
l     wChNo:标识通道号。
l     返回值:为1表示检测到忙音;为0,表示没有检测到忙音。
(13)Sig_ResetCheck函数
该函数用于清空忙音检测的缓冲区以及内部计数。当检测对方挂机的忙音后,必须调用本函数。语法如下:
        [DllImport("NewSig.DLL", CharSet = CharSet.Auto)]
        public static extern void Sig_ResetCheck(short wChlNo);
参数说明如下。
l     wChNo:标识通道号。
(14)Sig_StartDial函数
该函数用于拨打电话号码。开始某通道的呼出过程。该函数只是设置通道的呼出缓冲区,真正的呼出过程需要循环调用Sig_CheckDial函数来逐步完成。语法如下:
        [DllImport("NewSig.dll", CharSet = CharSet.Auto)]
        public static extern int Sig_StartDial(short wChNo, [MarshalAs(UnmanagedType.LPArray)] byte[] DialNum, [MarshalAs(UnmanagedType.LPArray)] byte[] PreDialNum, short wMode);
参数说明如下。
l     wChNo:标识通道号。
l     DialNum:标识呼出号码。
l     PreDialNum:标识前导号码。
l     wMode:呼出检测的模式。
(15)Sig_CheckDial函数
该函数用于检测呼出结果。
在调用函数Sig_StartDial启动拨号过程后,就可以循环调用Sig_CheckDial函数维持拨号过程,并检测呼出的结果,直至得到结果为止。
拨号的一般过程如下。
1.如果参数PreDialNum不为空,则延迟1秒后拨出PreDialNum,如果参数PreDialNum为空,则直接进入步骤3。
2.检测PreDialNum是否已发完。如已发完转至步骤3。
3.检测是否有拨号音,如拨号音长度达到配置项DialToneAfterOffHook的数值,则发送DialNum码串,并转至步骤4。如在此步骤已等待配置项NoDialToneAfterOffHook定义的时间长度仍未检测到拨号音,则返回0x10。
4.检测DialNum码串是否发完,如已发完则延迟StartDelay配置项的时间长度后进入步骤5。
5.如果从进入此步骤起已经过配置项RingLen定义的时间长度,拨号音仍未停止则返回0x10;如果在此步骤已等待配置项NoRingLen定义的时间长度仍未检测到回铃音则返回0x10;如果检测到占线忙音数达到配置项BusySigCount定义的数字,则返回0x21;如果检测到对方摘机,则返回0x14;如果进入此步骤已经过配置项Ringback_NoAnswerTime定义的时间长度,并且已检测到回铃音,则返回0x13;其他情况返回0x10。
 注意:在进行呼出结果检测之前必须调用函数StartSigCheck启动信号音采集过程,并且在进行呼出结果检测时,要循环调用FeedSigFunc函数维持信号音采集过程。
语法如下:
        [DllImport("NewSig.dll", CharSet = CharSet.Auto)]
        public static extern int Sig_CheckDial(short wChNo);
参数说明如下。
l     wChNo:标识通道号。
l     返回值包括以下几种情况。
l     16(0x10):尚未得出结果。
l     15(0x0F):没有拨号音。
l     33(0x21):检测到对方占线的忙音。
l     20(0x14):对方摘机,可以进行通话。
l     19(0x13):振铃若干次,无人接听电话。
l     21(0x15):没有信号音。
 注意:关于语音卡其他函数语法请参见光盘中的本实例文件D161A.CS,该文件给出大部分语音卡的函数语法。
实现过程
(1)新建一个项目,命名为Ex13_11,默认窗体为Form1。
(2)在Form1窗体中,主要添加两个Button控件,用于执行电话拨号和电话挂机,添加一个DataGridView控件,显示语音卡各通道及通道状态,添加Timer组件实现电话的呼出过程,添加一个TextBox控件,用于输入呼出电话号码。
(3)主要程序代码。
在窗体装载事件中,主要进行初始化语音卡驱动程序,并且检测通道总数及状态,为每一条通道分配语音缓冲区。代码如下:
        private void Form1_Load(object sender, EventArgs e)
        {
           
            //初始化驱动程序
            long load = DJ160API.LoadDRV();
            //检测通道总数,并为每个通道分配语音缓冲区
            short wuseCh = DJ160API.CheckValidCh();
            short wFileBufLen = 16 * 1024;
            long card = DJ160API.EnableCard(wuseCh, wFileBufLen);
            //设置表格通道的行数
            dataGridView1.RowCount = wuseCh;
            //检测每个通道类型
            short chanelTpye = 0; //定义通道类型变量
            string strType = "";
            for (short i = 0; i < wuseCh; i++)
            {
                chanelTpye = DJ160API.CheckChType(i);
                dataGridView1[0, i].Value = i;
                switch (chanelTpye)
                {
                    case 0:
                        strType = "内线";
                        break;
                    case 1:
                        strType = "外线";
                        break;
                    case 2:
                        strType = "悬空";
                        break;
                }
                dataGridView1[1, i].Value = strType;
                dataGridView1[2, i].Value = "空闲";
            }
        }
在DataGridView控件中选择一个外线空闲通道,单击【拨号】按钮,进行电话拨号,并且将拨号过程中的状态显示在相应的DataGirdView表格中。代码如下:
        private void button1_Click(object sender, EventArgs e)
        {
            short wuseCh = DJ160API.CheckValidCh();
            short wFileBufLen = 16 * 1024;
            long card = DJ160API.EnableCard(wuseCh, wFileBufLen);
            DJ160API.Sig_Init(chanel);
            //检查(外线)是否有振铃信号或(内线)是否有提机
            bool ring = DJ160API.RingDetect(chanel);
            //外线提机
            DJ160API.OffHook(chanel);
            byte[] ss =new byte[textBox1.Text.Length];
            byte[] s ={ 0 };
            for (int i = 0; i < textBox1.Text.Length; i++)
            {
                ss[i] = Convert.ToByte(textBox1.Text.Substring(i, 1));
            }
            DJ160API.Sig_StartDial(chanel, ss, s, 0);
            timer1.Enabled = true;
            dataGridView1[2, chanel].Value = "拨号中...";
            dataGridView1[3, chanel].Value = textBox1.Text;
        }
单击【挂机】按钮,实现电话挂机功能。代码如下:
        private void button2_Click(object sender, EventArgs e)
        {
            DJ160API.HangUp(chanel);
            DJ160API.Sig_ResetCheck(chanel);
            DJ160API.StartSigCheck(chanel);
            timer1.Enabled = false;
            dataGridView1[2, chanel].Value = "空闲";
            dataGridView1[3, chanel].Value = "";
        }
Sig_StartDial函数用于拨打电话号码。开始某通道的呼出过程。该函数只是设置通道的呼出缓冲区,真正的呼出过程需循环调用Sig_CheckDial函数来逐步完成。代码如下:
        private void timer1_Tick(object sender, EventArgs e)
        {
            DJ160API.Sig_CheckDial(chanel);
        }
单击DataGridView控件的相应行记录相应的通道号,代码如下:
   private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            chanel = (short)e.RowIndex;
        }
举一反三

说明-3
根据本实例,读者可以开发以下程序。
  实现电话自助服务系统。
  实现电话自动报警系统。
实例429 客户来电查询系统
实例说明

说明-4
随着市场竞争的加剧,企业越来越重视客户服务和市场反馈。本例实现了电话来电的显示支持功能。当有客户打入电话时,会读取客户的电话号码,根据电话号码可以提取客户的相关信息,方便客服人员有针对性地进行服务。实例运行结果如图13.13所示。

图13.13  客户来电查询
技术要点
其他相关函数介绍请参见实例“语音卡电话呼叫系统”,本实例主要介绍GetCallerIDStr函数,该函数用于获取主叫号码。语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern short GetCallerIDStr(short wChnlNo, byte[] IDStr);
参数说明如下。
l     wChnlNo:标识通道号。
l     IDStr:用于接收读取的号码。
l     返回值:为0,表示未收到任何信息;为1,表示正在接收头信息;为2表示正在接收ID号码;为3表示接收完毕,校验正确;为4表示接收完毕,校验错误。
在调用GetCallerIDStr函数时,只有返回值为3或4才表示已经正确接收了主机号码。
实现过程
(1)新建一个项目,命名为Ex13_12,默认窗体为Form1。
(2)在Form1窗体中,主要添加一个DataGridView控件,显示语音卡各通道和通道状态,并在来电时显示来电号码;添加一个Timer控件用于时刻检测来电信息;添加其他控件及用途如图13.13所示。
(3)主要程序代码。
private void timer1_Tick(object sender, EventArgs e)
        {
            byte[] ss = new byte[100];
                for (short i = 0; i < 8; i++)
                {
                    DJ160API.StartSigCheck(i);
                    if(open_close==false)
                        DJ160API.ResetCallerIDBuffer(i);
                    if (DJ160API.RingDetect(i))
                    {
                        open_close = true;
                        //获取来电号码
                        result = DJ160API.GetCallerIDStr(i, ss);
                        if (result == 3 || result == 4)
                        {
                            string str = Encoding.UTF8.GetString(ss);
                            txtTel.Text = str;
                            txtTel.Text = txtTel.Text.Substring(txtTel.Text.Length - 8, 8);
                            dataGridView1[2, i].Value = txtTel.Text;
                            //查询客户资料
                            this.getMessage(txtTel.Text);
                        }
                    }
                }
        }
        private void getMessage(string str)
        {
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "db_csell.mdb" + ";Persist Security Info=False");
            OleDbDataAdapter dap = new OleDbDataAdapter("SELECT * FROM 个人名录表 WHERE 电话='" + str + "'", con);
            DataSet ds = new DataSet();
            dap.Fill(ds);
            if (ds.Tables[0].Rows.Count > 0)
            {
                txtName.Text = ds.Tables[0].Rows[0]["姓名"].ToString();
                txtDuty.Text = ds.Tables[0].Rows[0]["职务"].ToString();
                txtAddress.Text = ds.Tables[0].Rows[0]["地址"].ToString();
                txtMobile.Text = ds.Tables[0].Rows[0]["手机"].ToString();
                txtCompany.Text = ds.Tables[0].Rows[0]["公司名称"].ToString();
                txtPostId.Text = ds.Tables[0].Rows[0]["邮编"].ToString();
            }
            else
            {
                labStatus.Text = "非本单位会员客户。。。。";
            }
        }
举一反三

说明-5
根据本实例,读者可以开发以下程序。
  用语音卡实现客户某项费用的查询。
  用语音卡实现客户在某个时间的留言信息。
  用语音卡实现客户购买物品的查询。
  实现客户反馈电话录音系统。
实例430 语音卡实现电话录音
实例说明

说明-6
如今的许多电话都具有电话录音的功能。本例实现了该功能,当有电话打入时,即刻将双方的对话信息进行录音。实例运行结果如图13.14所示。
技术要点
其他相关函数介绍请参见实例“语音卡电话呼叫系统”,本实例主要介绍StartRecordFile函数和StopRecordFile函数。
(1)StartRecordFile函数用于开始文件录音。停止该方式的录音一定要用StopRecordFile函数。检查录音是否结束,用CheckRecordEnd函数。StartRecordFile函数语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern bool StartRecordFile(short wChnlNo, byte[] FileName, long dwRecordLen);
参数说明如下。
l     wChnINo:标识录音的通道号。
l     FileName:标识录音的文件名。
l     dwRecordLen:标识文件大小。
(2)StopRecordFile函数用于停止录音。该函数语法如下:
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern void StopRecordFile(short wChnlNo);
参数说明如下。
l     wChnINo:标识要停止的录音通道。
(3)CheckRecordEnd函数检查指定通道录音是否结束(缓冲区已满)。
        [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
        public static extern int CheckRecordEnd(int ChannelNo);
参数说明如下。
l     wChnINo:标识录音的通道号。
l     返回值:0表示未结束;1代表结束。
实现过程
(1)新建一个项目,命名为Ex13_13,默认窗体为Form1。
(2)在Form1窗体中,主要添加一个DataGridView控件,显示语音卡各通道和通道状态,并在来电时显示来电号码;添加一个Timer控件用于实时检测来电信息,如果来电,程序将自动摘机并且实现录音;添加其他控件及用途如图13.14所示。
(3)主要程序代码。
        private void timer1_Tick(object sender, EventArgs e)
        {
            //维持文件录音持续执行
            DJ160API.PUSH_PLAY();
            for (short i = 0; i < 8; i++)
            {
                DJ160API.StartSigCheck(i);
                if (open_close == false)
                    DJ160API.ResetCallerIDBuffer(i);
                if (DJ160API.RingDetect(i))
                {
                    open_close = true;
                    //摘机
                    DJ160API.OffHook(i);
                    DJ160API.StartSigCheck(i);
                    //是否挂机
                    if (DJ160API.ReadCheckResult(i, 2) != 33)
                    {
                        bool bl = DJ160API.StartRecordFile(i, Encoding.UTF8.GetBytes(@"D:/ly.001"), 600 * 1024);
                        dataGridView1[2, i].Value = "已接来电,开始录音";
                    }
                    else
                    {
                        DJ160API.StopRecordFile(i);
                        open_close = false;
                        DJ160API.Sig_ResetCheck(i);
                        dataGridView1[2, i].Value = "";
                    }
                    if (DJ160API.CheckRecordEnd(i)==1)
                    {
                        DJ160API.StopRecordFile(i);
                        open_close = false;
                        dataGridView1[2, i].Value = "";
                    }
                }
            }
        }

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/long102/archive/2007/10/31/1859287.aspx

最近,正在忙基于三汇语音卡呼叫中心的项目,真的好迷糊啊!公司在呼叫中心这方面的研发是空白,所有的资料都得从零开始收集,分析,上网查找一些前辈们的技术资料,在这里备个份,好好学习一下! --------------------------------------------------------------------------------------------------------------------- 随着语音技术的不断发展,语音卡在通信行业应用非常广泛。本节通过几个典型实例介绍语音卡程序的开发。 说明-1 实例428 语音卡电话呼叫系统 实例说明 随着科学技术的不断发展,语音卡被广泛地应用于商业软件中。本例实现了利用语音卡实现电话呼叫的功能。实例运行结果如图13.12所示。 说明-2 技术要点 本例采用东进公司开发的8路模拟语音卡,该卡采用灵活的模式化设计,可按需配置外线、内线两种模块。该语音卡实现坐席、会议、FSK数据收发、语音合成等多种功能,并提供SDK开发工具包。 在安装完驱动程序后,相应的动态链接库(NewSig.dll和Tc08a32.dll文件)会复制到Windows的系统目录下。在语音卡的开发过程中,主要通过调用NewSig.dll和Tc08a32.dll来实现相应的功能。下面介绍这两个动态库中的主要使用函数。 (1)LoadDRV函数 该函数用于加载动态链接库。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long LoadDRV(); 返回值:返回值为0表示成功;?1表示打开设备驱动程序错误。?2表示在读取TC08A-V.INI文件时发生错误;?3表示INI文件的设置与实际的硬件不一致时发生错误。 (2)FreeDRV函数 该函数用于关闭驱动程序。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long EnableCard(short wusedCh, short wFileBufLen); (3)EnableCard函数 该函数用于初始化语音卡硬件,并为每个通道分配语音缓冲区。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern long EnableCard(short wusedCh, short wFileBufLen); 参数说明如下。 l wUsedCh:标识通道数量。 l WFileBufLen:标识分配的缓冲区大小。 (4)CheckValidCh函数 该函数检测在当前机器内可用的通道总数。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern short CheckValidCh(); l 返回值:通道总数量。 (5)CheckChType函数 该函数用于测试某个通道的类型。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern short CheckChType(short wChnlNo); 参数说明如下。 l wChnlNo:标识通道号。 l 返回值:为0表示内线;为1表示外线;为2表示悬空。 (6)PUSH_PLAY函数 该函数用于维持文件录放音的持续进行,需在处理函数的大循环中调用。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern void PUSH_PLAY(); (7)SetBusyPara函数 该函数用于设置要检测的挂机忙音的参数。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern void SetBusyPara(short BusyLen); 参数说明: l BusyLen:标识忙音的时间长度,单位为毫秒。 (8)RingDetect函数 该函数用于测试外线是否振铃或内线是否提机。语法如下: [DllImport("Tc08a32.dll", CharSet = CharSet.Auto)] public static extern bool RingDetect(short wChnlNo); 参数说明如下。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值