QT5音频开发:使用QAudioOutput播放WAV文件,可使用指定的声卡进行播放

一、环境介绍

操作系统:  windows10 64位

QT版本:5.12.6

二、功能介绍

封装了一个播放WAV文件的类,可以播放指定的WAV文件、并且可以指定放声音的扬声器设备,在有多个声卡的系统上非常实用。

 

代码里主要注意的地方:在其他系统上运行,需要注意结构体的字节对齐问题,WAV头结构体正常字节大小是44字节。如果在Linux系统下运行如果无法播放WAV,要注意打印下WAV头结构体大小是否是44字节。

(不同位数的系统下, unsigned long 类型占用的字节不一样,WAV头结构体里存在 unsigned long类型,在其他系统运行需要注意下,为了兼容可以修改成 unsigned int)

 

三、核心代码

3.1  widget.cpp文件代码

#include "widget.h"
#include "ui_widget.h"
#include 
#include 
#include 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
          qDebug() << "当前系统可用的声卡设备: " << deviceInfo.deviceName();

}

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

void Widget::wav_file_play(QString file)
{
    WAV_PLAY *wav_play;
    //这里可使用指定的声卡进行播放这里默认使用系统的默认声卡
    //要使用指定声卡,替换第一个参数即可,可看构造函数里打印的可用设备
    wav_play=new WAV_PLAY(QAudioDeviceInfo::defaultOutputDevice(),file);
    wav_play->play();
}

void Widget::on_pushButton_clicked()
{
    wav_file_play("D:/linux-share-dir/12804.wav");
}

3.2 widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include "wav_play.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void wav_file_play(QString file);
private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

3.3  wav_play.cpp文件代码

#include "wav_play.h"
WAV_PLAY::WAV_PLAY(QAudioDeviceInfo info,QString wav_file)
{
    audio=nullptr;
    inputFile=nullptr;
    thread=nullptr;

    inputFile=new QFile;
    inputFile->setFileName(wav_file);
    if(inputFile->open(QIODevice::ReadOnly)==false)
    {
        qDebug()<<"文件打开失败.";
        QObject::deleteLater(); //释放资源
        return;
    }

    // 开始读取WAV的文件头
    WAVFILEHEADER WavFileHeader;
    if(inputFile->read((char*)&WavFileHeader,sizeof (WavFileHeader))!=sizeof (WavFileHeader))
    {
        qDebug()<<"读取WAV文件头失败.";
        QObject::deleteLater(); //释放资源
        return;
    }

    //打印读取到的信息
    qDebug()<<"RiffName:"<moveToThread(thread); //移动到子线程运行
    //播放状态
    connect(audio,SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged_input(QAudio::State)),Qt::QueuedConnection);
    thread->start();
}


WAV_PLAY::~WAV_PLAY()
{
    qDebug()<<"开始资源释放";
    if(audio)
    {
        audio->stop();
        delete audio;
    }
    if(inputFile)
    {
        inputFile->close();
        delete inputFile;
    }
    qDebug()<<"资源释放成功";
}

void WAV_PLAY::play()
{
    if(audio)audio->start(inputFile);
}

//播放状态
void WAV_PLAY::handleStateChanged_input(QAudio::State newState)
{
    //开始
    if(newState==QAudio::ActiveState)
    {

    }
    //播放完成
    /*
    传入的QIODevice没有数据,并且音频系统的缓冲区为空,
    此状态在调用start()之后并且没有音频数据可用于处理时设置。
    */
    if(newState==QAudio::IdleState)
    {
        QObject::deleteLater();
        thread->exit();
    }
}

3.4 wav_play.h代码

#ifndef WAV_PLAY_H
#define WAV_PLAY_H
#include 
#include 
#include 
#include 
#include 
#include 

//WAV文件结构体信息
struct WAVFILEHEADER
{
    // RIFF 头
    char RiffName[4];
    unsigned long nRiffLength;

    // 数据类型标识符
    char WavName[4];

    // 格式块中的块头
    char FmtName[4];
    unsigned long nFmtLength;

    // 格式块中的块数据
    unsigned short nAudioFormat;
    unsigned short nChannleNumber;
    unsigned long nSampleRate;
    unsigned long nBytesPerSecond;
    unsigned short nBytesPerSample;
    unsigned short nBitsPerSample;

    // 数据块中的块头
    char    DATANAME[4];
    unsigned long   nDataLength;
};


class WAV_PLAY:public QObject
{
    Q_OBJECT
public:
    WAV_PLAY(QAudioDeviceInfo info, QString wav_file);
    ~WAV_PLAY();
    QFile *inputFile;
    QAudioOutput *audio;
    QThread *thread;
    void play();
public slots:
    void handleStateChanged_input(QAudio::State newState);
};
#endif // WAV_PLAY_H

四、运行效果

界面比较简陋,只是为了测试代码。

QT5音频开发:使用QAudioOutput播放WAV文件,可使用指定的声卡进行播放_第1张图片

 

 

下面公众号里有全套的QT\C++\C\单片机教程,欢迎关注:

QT5音频开发:使用QAudioOutput播放WAV文件,可使用指定的声卡进行播放_第2张图片

 

 

你可能感兴趣的:(QT,LINUX)