【音视频开发系列】QT 采集麦克风PCM并播放

12 篇文章 0 订阅

[注] 调试前请先戴耳机,作为测试使用,没有项目的严谨,需要自调,适合做回声消除类似的测试用例

项目地址: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();
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值