windows下使用Qt播放PCM音频文件(通过QAudioOutput和QIODevice)

版权声明: https://blog.csdn.net/u014552102/article/details/84556096

  在博主之前的博文《windows下使用FFmpeg生成PCM音频文件并播放(通过命令的方式)》(链接https://blog.csdn.net/u014552102/article/details/82734278)中,介绍了通过FFmpeg命令播放PCM音频文件的方法。本文介绍通过Qt的控件(通过QAudioOutput和QIODevice)播放PCM音频文件的方法。开发环境是Qt5.9.0 + vs2015 + win7。

一、代码展示 

  整个程序的流程是先通过QAudioFormat设定音频数据格式,将音频文件audio1.pcm的数据读取到缓冲区buf中,然后通过QIODevice的write函数将buf中的数据提交到声卡。audio1.pcm音频文件用的是博主之前博客中的音频文件(链接https://blog.csdn.net/u014552102/article/details/82734278),该PCM音频文件是用ffmpeg命令生成的,大家可以通过查看博主的那篇文章得到该音频文件。整个程序的代码如下:

#include <QtCore/QCoreApplication>
#include <QAudioFormat>
#include <QAudioOutput>
#include <QThread>


int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	
	QAudioFormat fmt; //通过fmt设定音频数据格式。只有明确知道音频数据的声道数、采样率、采样位数,才可以正常地播放
	fmt.setSampleRate(44100);  //设定播放采样频率为44100Hz的音频文件
	fmt.setSampleSize(16);     //设定播放采样格式(采样位数)为16位(bit)的音频文件。QAudioFormat支持的有8/16bit,即将声音振幅化为256/64k个等级
	fmt.setChannelCount(2);    //设定播放声道数目为2通道(立体声)的音频文件。mono(平声道)的声道数目是1,stero(立体声)的声道数目是2
	fmt.setCodec("audio/pcm"); //播放PCM数据(裸流)得设置编码器为"audio/pcm"。"audio/pcm"在所有的平台都支持,也就相当于音频格式的WAV,以线性方式无压缩的记录捕捉到的数据。如想使用其他编码格式 ,可以通过QAudioDeviceInfo::supportedCodecs()来获取当前平台支持的编码格式
	fmt.setByteOrder(QAudioFormat::LittleEndian); //设定字节序,以小端模式播放音频文件
	fmt.setSampleType(QAudioFormat::UnSignedInt); //设定采样类型。根据采样位数来设定。采样位数为8或16位则设置为QAudioFormat::UnSignedInt
	QAudioOutput *out = new QAudioOutput(fmt);    //创建QAudioOutput对象并初始化
	QIODevice *io = out->start(); //调用start函数后,返回QIODevice对象的地址

	int size = out->periodSize();
	char *buf = new char[size];           //创建缓冲区buf
	FILE *fp = fopen("audio1.pcm", "rb"); //打开音频文件audio1.pcm获取文件指针fp。r是以只读方式打开资源,b是不转义数据,就是不认转义字符,告诉函数库打开的文件为二进制文件,而非纯文字文件。注意如果写成FILE *fp = fopen("audio1.pcm", "r")会播放不了音频文件
	while (!feof(fp)) //测试文件指针是否到了文件结束的位置。也就是判断音频文件audio1.pcm是否读完了
	{
		if (out->bytesFree() < size)
		{
		    QThread::msleep(1); //这里如果不加延时,运行代码时,CPU占用率会极大。如果延时时间太长,比如1000ms,播放时声音会一卡一卡,这里选择延时1ms。
			continue;
		}
		int len = fread(buf, 1, size, fp); //将音频文件audio1.pcm的PCM数据读取到内存buf中

		if (len <= 0)  //如果读取到文件末尾或者读取不成功则通过break函数跳出while循环
		{
			break;
		}

		io->write(buf, len); //调用write函数将内存buf中的PCM数据写入到扬声器,即把buf中的数据提交到声卡发声
	}
	fclose(fp);          //关闭文件描述符fp
	if(NULL != buf)      //释放buf的空间
	{
		delete buf;
		buf = NULL;
	}
	if (NULL != out)     //释放out的空间
	{
		delete out;
		out = NULL;
	}
	return a.exec();
}

编译,然后运行,可以听到电脑成功播放出音乐,证明程序运行成功了。

二、注意问题

  如果想成功编译上述程序,得在"Qt Project Settings"中选中Multimedia模块,如下图所示,否则编译会报错“无法打开包括文件: “QAudioFormat”: No such file or directory”。

猜你喜欢

转载自blog.csdn.net/u014552102/article/details/84556096