当前位置:网站首页>【音视频开发系列】QT 采集麦克风PCM并播放
【音视频开发系列】QT 采集麦克风PCM并播放
2022-08-04 05:34:00 【_杜竞宁_】
[注] 调试前请先戴耳机,作为测试使用,没有项目的严谨,需要自调,适合做回声消除类似的测试用例
项目地址:https://github.com/dujingning/PcmCaptureAndPlay
1.创建 QT 项目
2.pro文件添加
QT += multimedia
3添加类 .PcmCaptureAndPlay
①pcmcaptureandplay.h
/* * auth: dujingning * date: 2022.05.03 * licenst: MIT */
#ifndef PCMCAPTUREANDPLAY_H
#define PCMCAPTUREANDPLAY_H
#include <QThread>
#include <QDebug>
#include <QTimer>
#include <QFile>
#include <QAudio>
#include <QAudioFormat>
#include <QAudioInput>
#include <QAudioOutput>
#include <QIODevice>
class PcmCaptureAndPlay: public QThread
{
Q_OBJECT
public:
PcmCaptureAndPlay();
private: /* QT audio play */
QAudioFormat qAudioFormat;
QAudioOutput *out;
QIODevice *audioIO;
QTimer *audioPlayTimer;
QThread *timerTHread;
bool initQtAudioForPlay();
private: /* QT audio capture */
QAudioFormat format;
QAudioInput* audioInput;
QIODevice *qIODevice;
QFile file; // 可以输出到文件,咱不用,直接播
bool initQtAudioForCapture();
private: /* QT audio capture */
void audioCaptureAndPlay();
public slots:
void onReadyRead(); /*采集并填充*/
public:
void run();
};
#endif // PCMCAPTUREANDPLAY_H
② pcmcaptureandplay.cpp
#include "PcmCaptureAndPlay.h"
PcmCaptureAndPlay::PcmCaptureAndPlay()
{
}
bool PcmCaptureAndPlay::initQtAudioForPlay()
{
qAudioFormat.setSampleRate(16000);
qAudioFormat.setChannelCount(1);
qAudioFormat.setSampleSize(16);
qAudioFormat.setCodec("audio/pcm");
qAudioFormat.setByteOrder(QAudioFormat::LittleEndian);
qAudioFormat.setSampleType(QAudioFormat::SignedInt);
out = new QAudioOutput(qAudioFormat);
if (!out) {
return false;
}
audioIO = out->start();
return true;
}
bool PcmCaptureAndPlay::initQtAudioForCapture()
{
qIODevice = nullptr;
format.setSampleRate(16000);
format.setChannelCount(1); // 设定声道数目,mono(平声道)的声道数目是1;stero(立体声)的声道数目是2
format.setSampleSize(16); // 采样位深
format.setCodec("audio/pcm"); // 设置唯一支持的codec
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
format = info.nearestFormat(format);
}
file.setFileName("test.raw");
file.open( QIODevice::WriteOnly | QIODevice::Truncate );
audioInput = new QAudioInput(format, nullptr);
qIODevice = audioInput->start(); // 这里可以直接写入到文件,咱不用直接就是播放 audioInput->start(file);
if (qIODevice) {
qDebug() << "device available";
return true;
}
return false;
}
void PcmCaptureAndPlay::onReadyRead()
{
qint64 len = 0, size = 4096;
char buffer[4096]{
0};
len = qIODevice->read(buffer, size); //读取音频
if (len <= 0) {
return;
}
qDebug() << "read pcm size" << len;
qint64 bufferPlay = out->periodSize();
if (out->bytesFree() < bufferPlay) {
//
qDebug() << "play buffer not enough";
return;
}
audioIO->write((const char*)(buffer),len);
}
void PcmCaptureAndPlay::audioCaptureAndPlay()
{
initQtAudioForPlay(); // for play
initQtAudioForCapture(); // for capture
connect(qIODevice, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}
void PcmCaptureAndPlay::run()
{
audioCaptureAndPlay();
exec();
}
3.使用
PcmCaptureAndPlay *PCAP = new PcmCaptureAndPlay;
PCAP->start();
边栏推荐
猜你喜欢
随机推荐
指针运算相关面试题详解【C语言】
Memory Management
SSO单点登陆
基于Webrtc和Janus的多人视频会议系统开发7 - publish和subscribe声音设备冲突导致对方听不到声音
PS像素画学习-1
升级到 MediaPlayer 11 时跳过验证副本的方法
Uos统信系统 本地APT源配置
基于语音识别的QT设计的csgo互动类视频游戏
Prematurely reached end of stream
安全漏洞是如何被发现的?
对渗透测试工程师来说,学历重要嘛?
IP 核之 MMCM/PLL 实验
Uos统信系统 DNS
淘宝分布式文件系统存储引擎(一)
复杂格式的json转递
数据库实体类对应daoimpl,基础的增删改查。
Multi-threaded sequential output
第九篇 ApplicationContext初始化
怎样才能转行成功?
sql常用函数