qt音频录制和播放

  • Post author:
  • Post category:其他


使用qaudioinput和qaudiooutput类,利用电脑声卡录制环境声音信息存储到数组中,然后播放数组中存放的内容。

当前存在问题:播放的音频噪声较大,且播放的内容会被重新录制,导致重复播放。

//main.cpp
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QAudioFormat>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QAudioOutput>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
private slots:
    void onReadyRead();                     //注意onReadyRead需有槽函数声明
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void initInput();                       //初始化录放音设备
    void initOutput();
    QAudioFormat fmtIn;
    QAudioFormat fmtOut;
    QAudioDeviceInfo devIn;
    QAudioDeviceInfo devOut;
    QAudioInput *audioInput;
    QAudioOutput *audioOutput;
    QIODevice *inputDevice;
    QIODevice *outputDevice;
    QByteArray data[2000];
    qint64 sampleLen,sampleMaxLen;          //一次最多可读入的数据长度
    char buffer[4096]{0};
    int dataLen;                            //当前读入的数据长度
    int cnt;                                //当前数组下标
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    sampleLen=0;
    sampleMaxLen=4096;
    cnt=0;
    initInput();
    initOutput();
    //将QIODevice指向输入输出流
    inputDevice=audioInput->start();
    outputDevice=audioOutput->start();
    //有信号输入即触发readyRead(),转到onReadyRead()槽函数执行
    //若采用录制一段时间再取出则当前数据会覆盖前面的数据导致无法成功播放
    connect(inputDevice,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initInput() {
    fmtIn.setSampleRate(8000);                        //采样率HZ
    fmtIn.setSampleSize(8);                           //采样大小
    fmtIn.setChannelCount(1);                         //声道数
    fmtIn.setCodec("audio/pcm");                      //编解码器
    fmtIn.setByteOrder(QAudioFormat::LittleEndian);   //字节序,小端模式
    fmtIn.setSampleType(QAudioFormat::SampleType(1)); //采样类型
    devIn = QAudioDeviceInfo::defaultInputDevice();
    while(!devIn.isFormatSupported(fmtIn))       //录音设备是否支持,若不支持则提供最相似设备
    {
        fmtIn=devIn.nearestFormat(fmtIn);
    }
    qDebug() << "in device" <<devIn.deviceName();
    audioInput=new QAudioInput(devIn,fmtIn,this);
}

void MainWindow::initOutput() {
    fmtOut.setSampleRate(8000);
    fmtOut.setSampleSize(8);
    fmtOut.setChannelCount(1);
    fmtOut.setCodec("audio/pcm");
    fmtOut.setByteOrder(QAudioFormat::LittleEndian);
    fmtOut.setSampleType(QAudioFormat::SampleType(1));
    devOut = QAudioDeviceInfo::defaultOutputDevice();
    while(!devOut.isFormatSupported(fmtOut))
    {
        fmtOut=devOut.nearestFormat(fmtOut);
    }
    qDebug() << "out device" <<devOut.deviceName();
    audioOutput=new QAudioOutput(devOut,fmtOut,this);
}

void MainWindow::onReadyRead() {
    //最多读取sampleMaxLen个数据到buffer中,返回读取的数据个数    
    sampleLen = inputDevice->read(buffer,sampleMaxLen);         
    if(cnt==2000) return;
    data[cnt]=buffer;
    //播放
    outputDevice->write(data[cnt]);                             
    cnt++;
}



版权声明:本文为weixin_46090955原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。