主要用到以下三个类:
QAudioDeviceInfo类提供音频输出设备
QAudioFormat类提供音频参数设置
QAudioOutput类提供了用于将PCM原始音频数据发送到音频输出设备的接口。
1.引入头文件并打开PCM文件
#include <QtCore/QCoreApplication>
#include<qaudioformat.h>
#include<qaudiooutput.h>
#include<qthread.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
FILE* fp = fopen("test.pcm","rb");
if (fp)
cout << "打开成功" << endl;
else
cout << "打开失败" << endl;
2.实例化QAudioFormat并设置参数
QAudioFormat fmt;
fmt.setSampleRate(44100);
fmt.setSampleSize(16);//采样位数
fmt.setChannelCount(2);
fmt.setCodec("audio/pcm");
fmt.setByteOrder(QAudioFormat::LittleEndian);//字节的次序,不是位的,比如16,小端16大端61
fmt.setSampleType(QAudioFormat::UnSignedInt);
3.开辟一个QAudioOutput空间,使用上面实例化后的对象fmt做为其new使构造函数的参数
并调用QAudioOutput的start方法开始播放(只是打开了开关,数据还未开始流动,要听到播放的声音需要后面用io->wirte()将PCM数据来播放)
QAudioOutput* out = new QAudioOutput(fmt);
QIODevice* io = out->start();
4.将需要播放的音频数据分批放进缓冲队列中并播放
int size = out->periodSize();
char* buf = new char[size];
while (!feof(fp))
{
if (out->bytesFree() < size)
{
QThread::msleep(1);
continue;
}
int len=fread(buf, 1, size, fp);
if (len <= 0)
break;
io->write(buf, len);
}
fclose(fp);
delete buf;
buf = 0;
return a.exec();
}
out->periodSize()为传入数据的大小
当缓冲区的空余大小小于一次放入的数据大小时,进入等待,等到缓冲区中多余的数据被播放了留出足够的空间了再往缓冲区放数据 ,用如下语句判断 if (out->bytesFree() < size)
int len=fread(buf, 1, size, fp);将fp指向的PCM数据读到buf中
用buf做为媒介连接QT与原文件
io->write(buf, len);//将重采样后的PCM传给QT,才开始真正播放