Qt实现基于G.729A(G729A)的语音聊天
一、G.729协议简介
G.729协议是由ITU-T的第15研究小组提出的,并在1996年3月通过的8Kbps的语音编码协议。
G.729系列主要有以下几种:
G.729—最基本的G.729标准协议,原始版
G.729A—精简版的G.729,兼容原始版G.729,对G.729一些算法进行简单处理,相当于降低了算法的复杂度
G.729B—加入了语音端点检测模块,在编码前对语音进行语音和静默音进行检测,然后分别对不同情况进行编码
G.729AB—就是G.729A中加入语音端点检测模块,兼容G.729B,目前G.729AB用得比较多
G.729协议的实现是开源的,源码可以从ITU官网下载。
下载链接:https://www.itu.int/rec/T-REC-G.729/e
本文采用VoiceAge公司封装的G.729A静态库进行语音的编解码。
下载链接:http://download.csdn.net/detail/caoshangpa/9496833
由于低带宽的需求,G.729通常应用于VoIP(Voice over Internet Protocol),比如说视频会议。G.729有两大特点。
1.占用带宽小
使用普通编码的语音通讯需要占用64Kbps的带宽,而G.729仅仅需要8Kbps。
2.占用CPU时间多
使用G.729时CPU的使用时间大约为G.711的4倍,所以使用G.729时需要注意设备是否有足够的处理能力。
二、聊天过程
1.初始化
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//设置采样格式QAudioFormat audioFormat;//设置采样率audioFormat.setSampleRate(8000);//设置通道数audioFormat.setChannelCount(1);//设置采样大小,一般为8位或16位audioFormat.setSampleSize(16);//设置编码方式audioFormat.setCodec("audio/pcm");//设置字节序audioFormat.setByteOrder(QAudioFormat::LittleEndian);//设置样本数据类型audioFormat.setSampleType(QAudioFormat::UnSignedInt);//获取设备信息QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();if (!info.isFormatSupported(audioFormat)){qDebug()<<"default format not supported try to use nearest";audioFormat = info.nearestFormat(audioFormat);}info = QAudioDeviceInfo::defaultOutputDevice();if (!info.isFormatSupported(audioFormat)) {qDebug()<<"default format not supported try to use nearest";audioFormat = info.nearestFormat(audioFormat);}audioInput = new QAudioInput(audioFormat, this);//将麦克风的音频数据传输到输入设备streamIn = audioInput->start();//当输入设备检测到数据时,调用槽函数slogReadDataconnect(streamIn, SIGNAL(readyRead()), SLOT(slogReadData()));audioOutput = new QAudioOutput(audioFormat, this);//将音频数据传输到输出设备,再由输出设备写入到扬声器streamOut = audioOutput->start();//创建UDP线程CUdpThread *udpThread=new CUdpThread();udpThreadFather=new QThread();udpThread->moveToThread(udpThreadFather);connect(udpThreadFather,SIGNAL(started()),udpThread,SLOT(run()));//启动线程udpThreadFather->start();connect(this,SIGNAL(signalSendData(const QByteArray &)),udpThread,SLOT(slotSendData(const QByteArray &)));connect(udpThread,SIGNAL(signalSendData(const QByteArray &)),this,SLOT(slotSendData(const QByteArray &)));
}
2.编码发送
void Widget::slogReadData()
{short srcAudio[L_FRAME]={0};unsigned char dstAudio[L_FRAME_COMPRESSED]={'\0'};if (!audioInput){qDebug() << "AudioInput Error";return;}QByteArray dataBuffer(BUFFER_SIZE,0);qint64 len1 = audioInput->bytesReady();if (len1 > BUFFER_SIZE){qDebug()<<"BUFFER_SIZE too small";return;}qint64 len2 = streamIn->read(dataBuffer.data(), len1);tempBuffer.append(dataBuffer.data(),len2);for(int i=0;i<tempBuffer.length()/(L_FRAME*2);i++){//char转shortmemcpy(srcAudio,tempBuffer.data()+i*L_FRAME*2,L_FRAME*2);//编码cg729Encoder.encode(srcAudio, dstAudio);QByteArray frame;//reinterpret_cast用于强制转换,这里将unsigned char *转换为const char *。frame.append(reinterpret_cast<const char*>(dstAudio),L_FRAME_COMPRESSED);signalSendData(frame);}tempBuffer.clear();
}
3.接收解码
void Widget::slotSendData(const QByteArray &byte_array)
{for(int i=0;i<byte_array.length()/L_FRAME_COMPRESSED;i++){unsigned char srcAudio[L_FRAME_COMPRESSED]={'\0'};short dstAudio[L_FRAME]={0};memcpy(srcAudio,(unsigned char*)byte_array.data()+i * L_FRAME_COMPRESSED,L_FRAME_COMPRESSED);//G729解码cg729Decoder.decode(srcAudio,dstAudio,0);//short转chartempframe.append((char *)dstAudio,L_FRAME * 2);if(audioOutput&&audioOutput->state()!=QAudio::StoppedState&&audioOutput->state()!=QAudio::SuspendedState){int chunks = audioOutput->bytesFree()/audioOutput->periodSize();while (chunks){if (tempframe.length() >= audioOutput->periodSize()){//写入到扬声器streamOut->write(tempframe.data(),audioOutput->periodSize());tempframe = tempframe.mid(audioOutput->periodSize());}else{//写入到扬声器streamOut->write(tempframe);tempframe.clear();break;}--chunks;}}}
}
三、演示效果
程序启动后,麦克风就开始工作了,聊天双方指定目的IP后,点击按钮1就可以进行聊天。如果不想对方听到自己的声音,点击按钮2关闭声音发送。
源码链接:见http://blog.csdn.net/caoshangpa/article/details/51225733的评论
原创不易,转载请标明出处:https://blog.csdn.net/caoshangpa/article/details/51225733
Qt实现基于G.729A(G729A)的语音聊天相关推荐
- android 电视语音遥控器,基于遥控器的Android电视语音聊天系统及其方法与流程
本发明涉及,尤其涉及一种基于遥控器的Android电视语音聊天系统及其方法. 背景技术: 随着科技越来越发展,电视机的功能也越来越强大,对于电视机,相对于传统电视机的单纯看电视功能,现有技术中,还支持 ...
- Java基于TCP(Socket)协议的网络语音聊天
Java基于TCP协议的网络语音聊天 本聊天是基于tcp协议进行的,其本质为:本地录音->将录音通过网络编程转发给他人->他人进行录音的播放. 所需知识:多线程,基于tcp协议的网络编程 ...
- 使用ZEGO SDK零基础搭建Android语音聊天应用
2021年初,Clubhouse引爆了在线语音聊天应用,字节跳动.小米.快手.映客等国内泛娱乐社交厂商已纷纷跟进,那么搭建一个类Clubhouse的语音聊天软件难吗? 其实Clubhouse的技术原理 ...
- 基于云平台的智能语音交互式灌溉系统
---------------------------------------------------------------------------------------------------- ...
- 【语音SBC算法】基于正交滤波器组的语音SBC算法设计与实现
数字语音编码是现代数字语音通信以及数字语音存储回放的前提和基础,对数字语音通信系统和数字语音存储回放系统的性能具有决定性的作用.目前,主要从编码速率.时延.语音回放质量等指标上研究高效的数字语音编码算 ...
- 基于DSP技术的多路语音实时采集与压缩处理系统
在语音的数字通信和数字存储等应用领域,需要对多路语音信号进行实时采集和压缩处理[1].如某语音记录设备,需要对8路语音信号进行实时采集和压缩处理,而且要求对采集到的语音数据的压缩率尽量高.一般地,当要 ...
- Qt Linguist基于文本ID的翻译
Qt Linguist基于文本ID的翻译 基于文本ID的翻译 使用文本ID进行国际化 使用文本ID进行本地化 高级用法 基于文本ID的翻译 文本ID转换机制是用于国际化和本地化的"工业力量& ...
- stm32 交换机芯片_基于STM32的全链路语音交互 - stm32/stm8 - 电子工程世界
硬件平台:STM32F746G-DISC开发板 编译软件:KEIL 5.31 操作系统:RTX5 TCP/IP协议栈:Cyclone-TCP 语音交互平台:思必驰DUI开放平台 这里说一下使用的TCP ...
- 传统语音增强——基于先验信噪比的维纳滤波语音降噪算法
一.基于先验信噪比的维纳滤波语音降噪算法的基本概念 改进的维纳滤波器为基于先验信噪比的维纳滤波器,其原理框图下图所示. 对于第m帧带噪语音信号ym(n)=sm(n)+nm(n) 式中,sm(n)是第m ...
最新文章
- Android采用Application总结一下
- Python常用6个技术网站汇总分享!
- MySQL数据库提升篇-----触发器
- Java基础-锁机制
- Django 3.2.5博客开发教程:体验数据查询
- SQL SERVER – Beginning of SQL Server Architecture – Terminology – Guest Post
- Chipmunk僵尸物理对象的出现和解决(七)
- 挑战程序设计竞赛: 三角形
- FAT文件系统详解(一)
- 如何控制局域网网速_水星无线路由器怎么设置网速限制【设置方法】
- PING命令结果中的TTL是什么?
- oracle 误删数据恢复
- 数字图像处理(3) — 基于白平衡的人脸美白算法
- 有关信息学竞赛的常见问题
- #140-(EZOI练习)[进制转换]汽车牌照
- NYOJ1239 引水工程(最小生成树,Prim)
- 视频背景音乐怎么一键消音
- 单片机php-cgi,STM32: 基于ChibiOS/RT实时系统的LED点阵显示系统 - 基于GD32F150C6T6 MCU...
- 利用ipv6搭建一台服务器
- 小程序实现返回上个页面并刷新上个页面的数据?(页面栈)
热门文章
- java tapestry_Java Web开发的轻便架构Tapestry5---简介
- python语言下,B站(bilibili)热门排行榜视频封面爬取程序V1.0 小白也能看懂,八十岁没牙老太太看完拿舌头都能爬封面!!
- 微信公众号成本分析服务器,分析:为什么微信公众号用户获取成本比App还高?...
- PPT设置自动保存时间 mac_群晖NAS设置苹果mac时间机器Time Machine备份
- CPA十二--外币会计报表折算的方法(转载)
- win7系统计算机文件夹缓慢,win7系统搜索文件很慢的两种解决方法
- LVGL 7.8.1生成二维码例程
- kubernetes资源管理平台ratel
- Java 批量压缩图片zip文件
- 选择高防空间应该注意什么?