1. 程式人生 > >關於QT中的音頻通信問題

關於QT中的音頻通信問題

ann win output 技術 end 來看 log str type

今天給大家講說一個新的東西,使用QT實現音頻通信的功能,挺起來是不是很高大上啊,哈哈,實際上我們只是使用一些接口做一些簡單的工作而已,並不是讓你寫一個傳輸協議和采集音頻信息,好了,那我們就來說一說關於在QT中是實現音頻通信的具體過程吧!

首先我們要是用到是UDP的通信協議和關於音頻信息的采集類和標準的輸入輸出設別的類,那麽我們分別是下面的幾個類:

QUdpSocket:在QT用用於udp通信的類

QAudioInput:音頻采集的類

QIODevice:標準輸入輸出設備

QAudioOutput:數據音頻的類

音頻采集端口

上邊的用到的類中分別用到了網絡模塊和多媒體模塊所以在工程文件中需要加入對網絡和多媒體的支持(*.pro文件):

技術分享
1 QT      += multimedia
2 QT      += network
View Code

首先我們在音頻的采集端口需要設置音頻采集的格式和傳輸的數據包的類型,使用QAudioInput的對象按指定的格式去采集音頻數據,代碼提供如下:

技術分享
 1 MainWindow::MainWindow(QWidget *parent) :
 2     QWidget(parent),
 3     ui(new Ui::MainWindow)
 4 {
 5     ui->setupUi(this);
 6     //設置聲音格式
 7
QAudioFormat format; 8 format.setSampleRate (8000); //設置采樣頻率 9 format.setChannelCount (1); //設置通道計數 10 format.setSampleSize (16); //設置樣本大小,一般為8或者16 11 format.setCodec ("audio/pcm"); //設置編碼格式 12 format.setSampleType (QAudioFormat::SignedInt); //設置采樣類型 13
format.setByteOrder (QAudioFormat::LittleEndian); //設置字節序為小端字節序 14 15 input = new QAudioInput(format, this); 16 17 videoWriteSocket = new QUdpSocket(this); 18 }
View Code

  接下來我們要定義音頻信息在網絡間傳輸的數據包格式:

技術分享
1 //音頻傳輸的數據包格式
2 struct videoPack{
3     char    data[1024];
4     int     lens;
5 };
View Code

  現在我們將音頻數據能夠采集出來了,接下來就是將音頻的數據寫入標準輸入設備最後寫到廣播端口,寫入:

技術分享
1         inputDevice = input->start ();
2         connect (inputDevice, SIGNAL(readyRead()),
3                  this, SLOT(onReadyRead()));
View Code 技術分享
 1 void MainWindow::onReadyRead ()
 2 {
 3     qDebug() << "send audioinput....";
 4     videoPack vp;
 5     memset (&vp, 0, sizeof(vp));
 6     //讀取音頻數據
 7     vp.lens = inputDevice->read (vp.data, 1024);
 8     videoWriteSocket->writeDatagram((const char*)&vp,
 9                                     sizeof(vp),
10                                     QHostAddress("224.0.0.0"),
11                                     10000);
12 }
View Code

好了,通過上邊的步驟,那麽你就能夠將音頻數據將它按指定的格式寫入廣播端口了,接下來就只需要在讀取端口讀取我們的音頻信息就可以了。

音頻讀取端口

首先我們要在讀取端口這邊設置和音頻采集端口的音頻采集格式和傳輸的數據包類型嚴格的一致,不然的話你是不能處理音頻信息的。

好了,接下來我們就來看一看如何使用udp的端口讀取音頻信息吧,代碼如下:

技術分享
 1 MainWindow::MainWindow(QWidget *parent) :
 2     QWidget(parent),
 3     ui(new Ui::MainWindow)
 4 {
 5     ui->setupUi(this);
 6     //窗口udp的套接字對象
 7     videoReadSocket = new QUdpSocket(this);
 8     //綁定到廣播端口
 9     videoReadSocket->bind (QHostAddress::AnyIPv4, 10000,
10                            QUdpSocket::ShareAddress
11                            | QUdpSocket::ReuseAddressHint);
12     //加入廣播組
13     videoReadSocket->joinMulticastGroup (QHostAddress("224.0.0.0"));
14     //如果有套接字動作將會觸發readyRead信號,我們將讀取音頻信息
15     connect(videoReadSocket, SIGNAL(readyRead()),
16             this, SLOT(readyReadSlot()));
17     //設置聲音格式
18     QAudioFormat format;
19     format.setSampleRate (8000);        //設置采樣頻率
20     format.setChannelCount (1);         //設置通道計數
21     format.setSampleSize (16);          //設置樣本大小,一般為8或者16
22     format.setCodec ("audio/pcm");      //設置編碼格式
23     format.setSampleType (QAudioFormat::SignedInt);   //設置采樣類型
24     format.setByteOrder (QAudioFormat::LittleEndian); //設置字節序為小端字節序
25     output = new QAudioOutput(format, this);
26 
27     //開啟讀取音頻數據的接口
28     outputDevice = output->start ();
29 }
View Code

那好我們再來看一看在readyReadSlot的槽函數的處理代碼吧

技術分享
1 void MainWindow::readyReadSlot ()
2 {
3     qDebug() << "video reveiver...";
4     videoPack vp;
5     memset (&vp, 0, sizeof(vp));
6     videoReadSocket->readDatagram ((char*)&vp, sizeof(vp));
7     outputDevice->write (vp.data, vp.lens);
8 }
View Code

經過上邊一系列過程,那麽我們可以試一試,是不是已經可以接受到音頻的信息了呢,另外說一句,在構造函數的中用到的對象,我都將他聲明在了這個類的聲明中,以私有成員的形式出現在了類中,我就不予給出了,大家自己在頭文件中加入相應的聲明就行了。

關於QT中的音頻通信問題