当前位置:网站首页>【音视频开发系列】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();
边栏推荐
猜你喜欢
随机推荐
IP 核之 MMCM/PLL 实验
淘宝分布式文件系统存储(二)
结构体传参-C语言
JUC并发容器——ConcurrentLinkedQueue
Miscellaneous [development] [VS Code] remote - SSD retry failed
罗斯50分
读取JDBC配置文件
MySQL stored procedure study notes (based on 8.0)
POI及EasyExcel
文件权限管理 ugo
网络安全求职指南
新冠病毒和网络安全的异同及思考
Stream API
Treating as key frame since WebRTC-SpsPpsIdrIsH264Keyframe is disabled 解决
Visualization and Animation Technology (VR System)
Uos统信系统 Postfix-smtps & Dovecot-imaps
JVM intro
网络安全行业是蓝景吗?
Operating System Random
硬件描述语言Verilog HDL学习笔记之模块介绍