一:样例流程

下图是音频采样PCM的一个过程。
在这里插入图片描述
模拟数据->采样:将对应格式的连续的模拟信号装转化为离散的数字信号。
采样->量化:就是尽可能最大化最具代表性的集结采样信息离散点,是原来的数据能够正常表达。
量化->编码:将这些量化的信息,转化为计算机能够识别的信息。
编码->数字信息:最后将这些信息转化为计算机能够处理的和样本信号,实现音视频的播放。

二:基本使用

具体操作流程请看我的资源里面的介绍。
ffmpeg入门及应用方法

三:PCM过程的一些参数分析

1.采样率:单位HZ(赫兹),它是每秒钟的周期性变动重复次数的计量,我们人耳听力的范围是(20HZ~20000HZ)。奈奎斯特采样定理,给我们一个概念,采样需要有一个范围,当信号频率高于我们人耳能够接受的最大范围的2倍的时候。我们能将信息完整的保留下来。奈奎斯特频率(英语:Nyquist frequency)是离散信号系统采样频率的一半,因瑞典裔美国工程师哈里·奈奎斯特(Harry Nyquist)或奈奎斯特-香农采样定理得名。采样定理指出,只要离散系统的奈奎斯特频率高于被采样信号的最高频率或带宽,就可以避免混叠现象。
2.采样大小:指每一个样本大小,也就是振幅。如果选择参数16,则是2^16次方大小。
3.声道数:多路声道声音效果会更好,声道数一般分为单声道,双声道,四声道。
4.编解码器:就是对音视频文件采样之后进行编解码。
5.字节序:本项目采用小端模式
6.采样类型:无符号int类型。

四:音视频文件采样命令

1.目的:将MP4,MP3等音视频文件转化为二进制文件。
2.命令:ffmpeg -i test.mp4 s16le out.pcm
解释:将test.mp4,通过小端模式(le)转化为short16位的转换方法,转化为out.pcm格式的二进制文件,输入到我们的播放设备中,我们就可以进行视听盛宴了。

五:简单项目实例简(基于Qt)

#include <QtCore/QCoreApplication>
#include <QAudioFormat>
#include <QAudioOutput>
#include <QThread>
#include <string>
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QAudioFormat fmt;
    fmt.setSampleRate(44100);                       //采样率HZ 20HZ-20000HZ
    fmt.setSampleSize(16);                              //采样大小  2^16 = 65535
    fmt.setChannelCount(2);                           //声道数
    fmt.setCodec("audio/pcm");                     //编解码器
    fmt.setByteOrder(QAudioFormat::LittleEndian);  //字节序,小端模式
    fmt.setSampleType(QAudioFormat::UnSignedInt);  //采样类型,无符号int型
    
	// TODO: 生成PCM文件,然后使用二进制读文件的方式,读出流写入播放设备中进行播放声音
	QAudioOutput* out = new QAudioOutput(fmt);
	QIODevice* io = out->start(); // 操作声音设备
	int size = out->periodSize();//一个播放周期的大小
	//out->bytesFree
	char* tmp = new char[size];  // 文件缓冲区
	
	string src = "out.pcm";
	ifstream in(src.c_str(), ios::in | ios::binary);
	if (!in) // 开发是否成功
	{
		return -1;
	}
	//QIODevice
	//ifstream
	while (!in.eof())
	{
		if (out->bytesFree() < size)
		{
			// 等待继续读取数据,然后进行播放
			continue;
		}
		in.read(tmp, size);
		streamsize count = in.gcount();
		if (count <= 0)
		{
			break;
		}
		io->write(tmp, count);  // 向声音设备中写入数据
	}
	// 关闭文件,释放缓冲区
	in.close();
	delete[] tmp;
	tmp = NULL;


    return a.exec();
}

更多推荐