音视频入门基础:PCM专题(2)——使用Qt播放PCM音频文件

 =================================================================

音视频入门基础:PCM专题系列文章:

音视频入门基础:PCM专题(1)——使用FFmpeg命令生成PCM音频文件并播放

音视频入门基础:PCM专题(2)——使用Qt播放PCM音频文件

音视频入门基础:PCM专题(3)——使用Audacity工具分析PCM音频文件

=================================================================

一、引言

  在上一节《音视频入门基础:PCM专题(1)——使用FFmpeg命令生成PCM音频文件并播放》中,介绍了通过FFmpeg命令播放PCM音频文件的方法。本文介绍通过Qt的控件(通过QAudioOutput和QIODevice)播放PCM音频文件的方法。开发环境是Qt5.9.0 + vs2015 + win7。

二、代码展示

整个程序的流程是先通过QAudioFormat设定音频数据格式,将音频文件audio1.pcm的数据读取到缓冲区buf中,然后通过QIODevice的write函数将buf中的数据提交到声卡。audio1.pcm音频文件是上一节《音视频入门基础:PCM专题(1)——使用FFmpeg命令生成PCM音频文件并播放》最后的“资源下载”中的文件,该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”。

  • 13
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt播放PCM音频,你可以使用QAudio类及其相关的子类。以下是一个基本的步骤: 1. **设置音频设备和格式**: 首先,你需要创建一个`QAudioDeviceInfo`对象,它代表系统的音频输入或输出设备。然后选择一个合适的音频格式,如QAudioFormat::Format_PCM_16Bit。 ```cpp QAudioDeviceInfo deviceInfo(QAudioDeviceInfo::defaultInputDevice()); QAudioFormat format; format.setSampleRate(44100); format.setChannelCount(2); // 双声道 format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleSize(16); ``` 2. **创建音频输出流**: 使用`QAudioOutput`类创建一个音频输出流,并将设备信息和格式设置到流中。 ```cpp QAudioOutput audioOutput(deviceInfo, format); if (!audioOutput.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open audio output: " << audioOutput.errorString(); } ``` 3. **读取和播放PCM数据**: PCM数据通常存储在一个文件或者内存缓冲区中。你可以读取PCM数据并逐帧发送给音频输出流。 ```cpp QByteArray pcmData; // 假设已经从文件读取到pcmData audioOutput.start(); while (pcmData.size()) { qint64 bytesPlayed = audioOutput.write(pcmData.data(), pcmData.size()); if (bytesPlayed < 0) { qWarning() << "Error playing audio: " << audioOutput.errorString(); break; } pcmData.remove(0, bytesPlayed); } audioOutput.stop(); ``` 4. **处理错误和结束**: 在整个播放过程中,记得检查错误并正确关闭资源。 ```cpp audioOutput.close(); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值