基于PC平臺(tái)的VoIP實(shí)現(xiàn)

相關(guān)專題: 中國(guó)聯(lián)通

1 序言

  近幾年來(lái)傳統(tǒng)電信業(yè)的發(fā)展勢(shì)頭逐漸減弱。 在激烈的市場(chǎng)競(jìng)爭(zhēng)中,電信業(yè)需要不斷地去尋找新的收入增長(zhǎng)點(diǎn)。VoIP在全球隨著技術(shù)的成熟及各種人為管制的放松,開(kāi)始進(jìn)入一個(gè)新的發(fā)展時(shí)期。低廉的費(fèi)用、低的帶寬、話音和數(shù)據(jù)應(yīng)用的集成以及應(yīng)用性廣泛等優(yōu)點(diǎn)使VoIP必然成為了人們的選擇。

  IP(Internet Protocol)電話是一種數(shù)字電話,是技術(shù)創(chuàng)新的一種通信服務(wù)業(yè)務(wù)。它把語(yǔ)音、壓縮編碼、打包分組、分配路由、存儲(chǔ)交換、解包解壓等交換處理在IP網(wǎng)或互聯(lián)網(wǎng)上實(shí)現(xiàn)語(yǔ)音通信。

  傳統(tǒng)的電話網(wǎng)是以電路交換方式傳輸語(yǔ)音,所要求的傳輸寬帶為64kbit/s。而VoIP是以IP分組交換網(wǎng)絡(luò)為傳輸平臺(tái),對(duì)模擬的語(yǔ)音信號(hào)進(jìn)行壓縮、打包等一系列的特殊處理,使之可以采用無(wú)連接的UDP協(xié)議進(jìn)行傳輸。不同編碼方案應(yīng)用于VoIP,使得話音可以以不同的速率進(jìn)行傳輸,使得VoIP的傳輸帶寬進(jìn)一步減小到5-11kbit/s。

  傳統(tǒng)的電話網(wǎng)絡(luò)都有自己遵循的協(xié)議,在呼叫過(guò)程中都要用到這些協(xié)議,比如用于電路交換的7號(hào)信令等。H.323和sip信令協(xié)議被廣泛應(yīng)用于VoIP網(wǎng)絡(luò)中。H.323是一個(gè)框架性協(xié)議,這一框架體系結(jié)構(gòu)包括H.323終端、網(wǎng)關(guān)、關(guān)守和MCU。網(wǎng)關(guān)是VoIP的重要組成部分,網(wǎng)關(guān)完成了兩項(xiàng)功能的轉(zhuǎn)換,媒體信息編碼的轉(zhuǎn)換和信令的轉(zhuǎn)換。通過(guò)這兩種轉(zhuǎn)換,網(wǎng)關(guān)將TCP/IP網(wǎng)和PSTN網(wǎng)連接連了起來(lái)。

2 VoIP軟件的實(shí)現(xiàn)

  一般IP電話的業(yè)務(wù)可分為3類: PC-to-PC, PC-to-Phone和Phone-to-Phone。這里主要是針對(duì)PC-to-PC的編程過(guò)程進(jìn)行介紹。

  IP電話的基本數(shù)據(jù)流程為:呼叫方經(jīng)錄音設(shè)備獲取音頻流,然后對(duì)音頻流進(jìn)行編碼、壓縮、打包處理。其中計(jì)算機(jī)對(duì)輸入的不同類型的數(shù)據(jù)進(jìn)行不同的處理(如果是音頻數(shù)據(jù),采用無(wú)連接的UDP協(xié)議進(jìn)行傳輸;如果是信令和數(shù)據(jù)則采用面向連接的TCP協(xié)議進(jìn)行傳輸),然后經(jīng)網(wǎng)絡(luò)傳輸?shù)奖唤蟹健1缓艚蟹浇邮盏綌?shù)據(jù)以后,再進(jìn)行一系列的反變換,解包、解壓和解碼,送入放音緩沖區(qū),經(jīng)音頻設(shè)備輸出語(yǔ)音。

  2.1 通信模塊的實(shí)現(xiàn)

  MFC中提供了封裝的Socket類,它提供了全面的由事件驅(qū)動(dòng)的Socket通信能力。程序必須按要求通過(guò)此Socket發(fā)送和接收數(shù)據(jù)。Winsock使用的是TCP協(xié)議或UDP協(xié)議,允許建立并保持一個(gè)到遠(yuǎn)程計(jì)算機(jī)上的連接,且可以在連接結(jié)束之前實(shí)時(shí)地進(jìn)行數(shù)據(jù)交換。用戶僅通過(guò)設(shè)置屬性并借助事件處理就能輕而易舉地連接到一個(gè)遠(yuǎn)程的計(jì)算機(jī)上。使用Winsock時(shí),通信的雙方需要選定相同的協(xié)議。TCP協(xié)議適用于傳送大容量、需要安全性保證的數(shù)據(jù)文件; 而UDP協(xié)議適用需要分別與很多下屬通信,或建立的連接比較多且為時(shí)變的情況,如語(yǔ)音通信。

  Socket是面向客戶/服務(wù)器模式設(shè)計(jì)的,它針對(duì)客戶和服務(wù)器程序提供了不同的系統(tǒng)調(diào)用。同時(shí)它還分為面向連接和無(wú)連接兩種類型。對(duì)于語(yǔ)音傳輸,由于語(yǔ)音對(duì)實(shí)時(shí)性要求高,所以采用無(wú)連接的形式。而對(duì)于信令和數(shù)據(jù)傳輸,對(duì)準(zhǔn)確性要求比較高,通常采用面向連接的形式。

  //服務(wù)器端

  sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建socket

  if (bind(sock,(sockaddr*)&serv,addlen)) //綁定

  {

  m_edit.SetWindowText("bind error");

  }

  listen(sock,5);

  AfxBeginThread(serthread,0); //調(diào)用線程

  //客戶端

  clisock=socket(AF_INET,SOCK_STREAM,0);// 創(chuàng)建socket

  while(connect(clisock,(sockaddr*)&(cli),sizeof(cli))!=0)

  {

  dlg->m_edit.SetWindowText("等待.....");

  for (int i=0;i<=65000;i++) //空循環(huán)

  for(int j=0;j<=200;j++);

  ………

  }

  2.2 音頻模塊的實(shí)現(xiàn)

  IP電話音頻功能的實(shí)現(xiàn)主要包括語(yǔ)音的錄制和播放。因?yàn)樵贗P電話中采集實(shí)時(shí)的音頻數(shù)據(jù)而不是WAVE文件,而且要把實(shí)時(shí)的語(yǔ)音數(shù)據(jù)傳輸出去,所以編程過(guò)程中采用了底層音頻處理函數(shù), 這些函數(shù)允許應(yīng)用程序直接與底層驅(qū)動(dòng)程序通信,對(duì)錄制和播放提供更靈活的控制。對(duì)于波形設(shè)備來(lái)說(shuō),不論是錄制還是播放波形,系統(tǒng)要處理的數(shù)據(jù)量都很大,為了少占用內(nèi)存,底層服務(wù)函數(shù)以數(shù)據(jù)塊為單位進(jìn)行處理, 應(yīng)用程序要自己分配內(nèi)存,并將內(nèi)存塊的地址、大小等信息告訴底層音頻驅(qū)動(dòng)程序。

  首先介紹幾個(gè)要用到的數(shù)據(jù)結(jié)構(gòu)。WAVEFORMATEX結(jié)構(gòu)定義了WAVE音頻數(shù)據(jù)文件的格式。WAVEHDR結(jié)構(gòu)定義了波形音頻緩沖區(qū)。讀出的數(shù)據(jù)首先要填充此緩沖區(qū)才能送音頻設(shè)備播放,聲音的采集和播放都是在操作這個(gè)音頻數(shù)據(jù)塊結(jié)構(gòu)。 實(shí)際上主要用到的就是第一個(gè)成員變量lpData,所以只要在分配緩沖區(qū)(內(nèi)存)的同時(shí)相應(yīng)分配WAVEHDR數(shù)據(jù)塊結(jié)構(gòu), 然后將緩沖區(qū)的指針賦給對(duì)應(yīng)的數(shù)據(jù)塊結(jié)構(gòu)的成員變量lpData,這樣當(dāng)一個(gè)緩沖區(qū)填滿后,也就是一個(gè)音頻數(shù)據(jù)塊填滿了,通過(guò)消息機(jī)制就可以在消息函數(shù)中進(jìn)行處理和播放,播放完后又可通過(guò)消息函數(shù)把緩沖區(qū)再送給音頻設(shè)備輸入驅(qū)動(dòng)程序,繼續(xù)進(jìn)行采集并播放。

  當(dāng)一次性分配多個(gè)緩沖區(qū)和數(shù)據(jù)塊結(jié)構(gòu)并賦給音頻設(shè)備輸入驅(qū)動(dòng)程序后,至于把哪個(gè)緩沖區(qū)填滿,然后再把哪個(gè)空緩沖區(qū)賦給設(shè)備輸入驅(qū)動(dòng)程序,不需人為干預(yù),完全由Windows控制。在程序設(shè)計(jì)中可以使用兩個(gè)數(shù)據(jù)塊,交替進(jìn)行,當(dāng)正播放第一個(gè)緩沖區(qū),就用第二個(gè)緩沖區(qū)接收。

  //檢查語(yǔ)音輸入/輸出設(shè)備

  if(!waveInGetNumDevs())

  {

  return FALSE;

  }

  if(!waveOutGetNumDevs())

  {

  return FALSE;

  }

  //打開(kāi)音頻設(shè)備之前,需要先設(shè)置音頻數(shù)據(jù)格式

  ……………

  //分配緩沖區(qū)所需要的內(nèi)存

  pWaveOutHdr=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));

  pWaveHdr1=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));

  pWaveHdr2=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));

  //放音緩沖區(qū)

  pOutBuffer1=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500);

  pOutBuffer2=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500);

  rBuffer=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); //接收緩沖區(qū)

  //打開(kāi)音頻設(shè)備

  result=waveOutOpen((LPHWAVEOUT)&hWaveOut,WAVE_MAPPER,(LPWAVEFORMATEX)&pcm.wf,(DWORD)hwnd,0L,  CALLBACK_WINDOW)

  2.3 語(yǔ)音壓縮模塊的實(shí)現(xiàn)

  VoIP帶寬比電路交換更窄的主要原因是對(duì)數(shù)據(jù)進(jìn)行了壓縮處理。VoIP除了可使用最普通的編碼技術(shù)G.711外,還可以采用G.728, G.729, G.723.1等其它多種編碼方案。

  G.711有A律和μ律兩種形式。G.711通常被稱為PCM(脈沖編碼調(diào)制)。如果在編程中選擇PCM編碼方式。

  G.711提供了良好的語(yǔ)音質(zhì)量,但是它的主要缺點(diǎn)是需要64Kbit/s的帶寬。所以在程序中靈活的選擇編碼方式是很重要的。

  ITU-T推薦的G.723.1標(biāo)準(zhǔn)可以同時(shí)支持兩種速率的編碼。一種是6.3kbit/s另一種是5.3kbit/s。所以,G.723.1在高速率下提供了好的通話質(zhì)量,是一種好的編碼方案。在程序中的實(shí)現(xiàn)是通過(guò)對(duì)G.723.1軟件包中相應(yīng)功能函數(shù)的調(diào)用來(lái)完成的,而且,在進(jìn)行壓縮以前要將G.723.1的鏈接庫(kù)導(dǎo)入程序中。

  在需要進(jìn)行壓縮時(shí),要調(diào)用下面G.723.1的編碼和解碼函數(shù):

  void Coder(FLOAT *DataBuff, char *Vout); //編碼

  void Decod(FLOAT *DataBuff, char *Vinp, short int Crc); //解碼

  2.4 RTP封裝

  因?yàn)檎Z(yǔ)音傳輸對(duì)實(shí)時(shí)性要求非常高, 所以在程序中要采用基于UDP的RTP傳輸。UDP無(wú)法做到避免分組丟失和確保分組有序傳輸,運(yùn)行在UDP上的RTP幫助實(shí)現(xiàn)了這些功能,RTP含有一個(gè)時(shí)間戳,可以利用這個(gè)時(shí)間戳來(lái)確保信息同步的傳輸給了目的用戶并計(jì)算出了時(shí)延和抖動(dòng)。

  在程序中要對(duì)語(yǔ)音數(shù)據(jù)進(jìn)行RTP格式封裝,使用了makertp()函數(shù)。而在解析是使用了isrtp()函數(shù)。

  LONG makertp(databuf *pdata,unsigned long ssrc_i,unsigned long timestamp_i,unsigned short seq_i,int spurt);

  BOOL isrtp(unsigned char *pkt,int len);

  在進(jìn)行RTCP 格式的封裝時(shí),使用了三個(gè)函數(shù):

  rtcp_make_sdes();

  rtcp_make_sr();

  rtcp_make_rr()。

3 結(jié)論

  本文主要是利用VC++語(yǔ)言來(lái)實(shí)現(xiàn)PC-to-PC的軟件電話,它提供給Internet用戶在全球任何地方上網(wǎng)便可以呼叫對(duì)方的能力,提高了通信效率,是一種新的通信模式。

來(lái)源:中國(guó)聯(lián)通網(wǎng)站


微信掃描分享本文到朋友圈
掃碼關(guān)注5G通信官方公眾號(hào),免費(fèi)領(lǐng)取以下5G精品資料
  • 1、回復(fù)“YD5GAI”免費(fèi)領(lǐng)取《中國(guó)移動(dòng):5G網(wǎng)絡(luò)AI應(yīng)用典型場(chǎng)景技術(shù)解決方案白皮書
  • 2、回復(fù)“5G6G”免費(fèi)領(lǐng)取《5G_6G毫米波測(cè)試技術(shù)白皮書-2022_03-21
  • 3、回復(fù)“YD6G”免費(fèi)領(lǐng)取《中國(guó)移動(dòng):6G至簡(jiǎn)無(wú)線接入網(wǎng)白皮書
  • 4、回復(fù)“LTBPS”免費(fèi)領(lǐng)取《《中國(guó)聯(lián)通5G終端白皮書》
  • 5、回復(fù)“ZGDX”免費(fèi)領(lǐng)取《中國(guó)電信5GNTN技術(shù)白皮書
  • 6、回復(fù)“TXSB”免費(fèi)領(lǐng)取《通信設(shè)備安裝工程施工工藝圖解
  • 7、回復(fù)“YDSL”免費(fèi)領(lǐng)取《中國(guó)移動(dòng)算力并網(wǎng)白皮書
  • 8、回復(fù)“5GX3”免費(fèi)領(lǐng)取《R1623501-g605G的系統(tǒng)架構(gòu)1
  • 本周熱點(diǎn)本月熱點(diǎn)

     

      最熱通信招聘

    業(yè)界最新資訊


      最新招聘信息