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

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

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


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


技术要点
本例采用东进公司开发的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;
        }
举一反三


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


随着市场竞争的加剧,企业越来越重视客户服务和市场反馈。本例实现了电话来电的显示支持功能。当有客户打入电话时,会读取客户的电话号码,根据电话号码可以提取客户的相关信息,方便客服人员有针对性地进行服务。实例运行结果如图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 = "非本单位会员客户。。。。";
            }
        }
举一反三


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


如今的许多电话都具有电话录音的功能。本例实现了该功能,当有电话打入时,即刻将双方的对话信息进行录音。实例运行结果如图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

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

  1. 硬件接口开发之USB电话录音盒来电显示

    除了上篇<硬件接口开发之Modem来电显>介绍的Modem来电显示,还可以采用USB电话录音盒来进行来电显示和电话录音功能,本文介绍如何在C#中实现该功能.首先我们看看我是如何在我的软件中 ...

  2. 企业级:基于语音卡呼叫中心系统 CTI语音服务器,电话排队系统,电话转接系统,电话录音系统

    <CTI通讯接口软件D081A>用  户  手  册 语音服务器软件源代码+用户手册+数据结构+开发文档 有需要的给我留言! 我的QQ  7732 4199  本系统基本上可以适用于 有语 ...

  3. 分享一个C#使用AT指令控制语音猫的例子

    阅读全文:http://www.cckan.net/forum.php?mod=viewthread&tid=61 先来说说 最近公司让开发一个语音猫充值的软件,就是拨打10086(虚拟)进行 ...

  4. 谈谈市场上常用语音芯片方案选型,录音芯片方案选型

    [系列专栏]:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来! <QT开发实战> <嵌入式通用开发实战> <嵌入式Linux开发实战> 转自:http:/ ...

  5. Java字节流读取shp_SHN系列语音卡调试文档.doc

    三汇系列语音卡 杭 州 三 汇 信 息 工 程 有 限 公 司修订记录 时间修订内容修订人版本批准人20-11-22创建郑王峰V0.102012-06-08完善DTMF收发方式部分以及STUN与NAT ...

  6. C#实现IVR(基于东进的语音卡)-3

    1 using System;   2 using System.Collections.Generic;   3 using System.Text;   4 using System.Runtim ...

  7. Delphi之东进模拟语音卡(D160A)可复用源码

    Delphi之东进模拟语音卡(D160A)可复用源码 作者:成晓旭 Blog:http://blog.csdn.net/cxxsoft (声明:欢迎转载,请保证文章的完整性) 设计简介: 1.   将 ...

  8. 东进语音卡 java_东进语音卡的声音文件格式

    转自东进论坛 语音卡只支持8K8bit a-law 单声道的 PCM.wave.mp3,您的立体声的mp3需要转换成单声道,8k 8bit的才能播放 问:怎么样把wav格式的文件转换成东进卡能播放的格 ...

  9. Delphi之东进模拟语音卡(D160A)可复用源码(转)

    计 简介: 1.   将卡.通道分别单独进行设计与封装. 2.   所有的外部操作接口都封装在卡类这一类. 3.   在我的项目中,在卡类这一级还增加了适配器或者代理,分别实现了Adapter或Pro ...

  10. 怎么控制物联网卡的流量使用?

    随着时代的发展,物联网卡俨然成为了一种新的发展趋势,他也在被越来越多的人所熟知认识.不过,虽然物联网卡的发展十分迅速,但是相信还是有相当大的一部分人对于物联网卡是不是很熟悉吧,那接下来我就来简单的介绍 ...

最新文章

  1. 【Leetcode】刷题之路3(python版)
  2. rsync安装与配置使用 数据同步方案(centos6.5)
  3. 【福利】计算机公开课合集(视频教程)
  4. MySQL之TCL(事务控制)语句
  5. SQL Server 建立索引视图并查看性能状况
  6. JDBC案例-用java操作数据库增删改查
  7. 【T3】运行时错误3709
  8. mysql数据库连接池锁_数据库连接池deadlock
  9. 微信公众号文章如何设置关键词自动回复链接
  10. 小程序or网页前端CSS选择器
  11. 迎合老板还是员工 结果导向CRM更受欢迎
  12. 普通路由器改4g路由器_4G工业路由器物联卡批发价格是多少?良心厂家推荐
  13. CrateDB三机三节点部署(Docker Overlay网络)
  14. i710750h和r74800h玩游戏哪个好 r7 4800h和i7 10750h哪个性能好
  15. anaconda3配置python2.7环境_Anaconda3+python3环境下如何创建python2环境(win+Linux下适用,同一个anaconda下py2/3共存)...
  16. 大O表示法(复杂度分析)
  17. 我是如何诱骗你的-高级钓鱼技术
  18. 微信聊天中上怎么用计算机,电脑可以上微信吗,教您电脑怎么用微信
  19. 2021福建往届高考成绩查询,2021福建省地区高考成绩排名查询,福建省高考各高中成绩喜报榜单...
  20. 零基础请进,影视解说必备的5个工具|不可错过的免费配音软件

热门文章

  1. swift调用api接口_如何在Swift中进行API调用
  2. 按键精灵post请求_[教程] 以本论坛为例,手把手教你使用按键精灵POST登陆网页...
  3. 线性回归中的交互效应(interaction)
  4. 超越阿里云,华为云服务器究竟有多厉害!
  5. 线性代数学习笔记——第六讲——矩阵的转置
  6. 计算机论文英文摘要范文,毕业论文英文摘要范文三篇
  7. html自动排版 vs,Visual Stidio Code (vscode)自定义HTML页面自动生成格式
  8. 成功三步曲:有勇、有谋、有德
  9. Android 传感器概述
  10. Ubuntu查看有线网卡eth0和eth1分别对应网卡型号