實例428 語音卡電話呼叫系統ide
實例說明
函數
隨着科學技術的不斷髮展,語音卡被普遍地應用於商業軟件中。本例實現了利用語音卡實現電話呼叫的功能。實例運行結果如圖13.12所示。工具
技術要點
開發工具
本例採用東進公司開發的8路模擬語音卡,該卡採用靈活的模式化設計,可按需配置外線、內線兩種模塊。該語音卡可實現坐席、會議、FSK數據收發、語音合成等多種功能,並提供SDK開發工具包。測試
在安裝完驅動程序後,相應的動態連接庫(NewSig.dll和Tc08a32.dll文件)會複製到Windows的系統目錄下。在語音卡的開發過程當中,主要經過調用NewSig.dll和Tc08a32.dll來實現相應的功能。下面介紹這兩個動態庫中的主要使用函數。spa
(1)LoadDRV函數設計
該函數用於加載動態連接庫。語法以下:orm
[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;
}
觸類旁通
根據本實例,讀者能夠開發如下程序。
實現電話自助服務系統。
實現電話自動報警系統。