概念
PCM(Pulse Code Modulation)也被称为 脉码编码调制。PCM中的声音数据没有被压缩。可以直接播放,不需要解码。如果是单声道的文件,采样数据按时间的先后顺序依次存入。(它的基本组织单位是BYTE(8bit)或WORD(16bit))。如果是双声道的文件,采样数据按时间先后顺序交叉地存入
衡量参数
采样频率(Sample Rate)对应
8kHz(电话)、44.1kHz(CD)、48kHz(DVD)。采样频率(nb_samples):每秒钟取得声音样本的次数。把音频文件放大,实际上都是一个一个的点,一秒钟有多少个横坐标的点,就是该音频的采样频率
对应AVCodecContext结构体中的sample_rate
声道数(Number of Channels)
常见的音频有立体声(stereo)和单声道(mono)两种类型,立体声包含左声道和右声道。另外还有环绕立体声等其它不太常用的类型。
对应AVCodecContext结构体中的channels
采样深度(Sample Size)
比特深度决定了文件的动态分辨率,类似照片分辨率。每个样本所含的比特越多,代表着动态范围越大。这并不意味,比特深度越高,音量越大;而是更高的比特深度听起来会更加真实,因为它们可以尽量减少音频失真度。也叫量化位数。通常该值为16-bit
对应FFmpeg (sample_fmt)
Sign
表示样本数据是否是有符号位,比如用一字节表示的样本数据,有符号的话表示范围为-128 ~ 127,无符号是0 ~ 255。
Byte Ordering
字节序。字节序是little-endian还是big-endian。通常均为little-endian。字节序说明见第4节。
Integer Or Floating Point
整形或浮点型。大多数格式的PCM样本数据使用整形表示,而在一些对精度要求高的应用方面,使用浮点类型表示PCM样本数据。
packed(交错)和planar(平面概念)
假设有一路音频流,有左右两声道的数据。左声道用L表示,右声道用R表示。
音视频都有packed和planar两种存储方式
- packed方式为多个声道交错存储,比如双声道data[0] = LRLRLR…
- planar方式为多个声道独立存储,比如双声道data[0] = LLL… data[1] = RRR…
音频帧
一般情况下,一帧PCM是由1024次采样组成的,这个由采样的编码格式决定的
对应AVCodecContext结构体中的frame_size
对应AVFrame结构体中的nb_samples
FFmpeg转码
支持的编解码格式
C:\Users\admin\Music>ffmpeg -formats | findstr PCM
ffmpeg version git-2020-08-16-5df9724 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 10.2.1 (GCC) 20200805
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libgsm --enable-librav1e --enable-libsvtav1 --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 58.100 / 56. 58.100
libavcodec 58.100.100 / 58.100.100
libavformat 58. 51.100 / 58. 51.100
libavdevice 58. 11.101 / 58. 11.101
libavfilter 7. 87.100 / 7. 87.100
libswscale 5. 8.100 / 5. 8.100
libswresample 3. 8.100 / 3. 8.100
libpostproc 55. 8.100 / 55. 8.100
DE alaw PCM A-law
DE f32be PCM 32-bit floating-point big-endian
DE f32le PCM 32-bit floating-point little-endian
DE f64be PCM 64-bit floating-point big-endian
DE f64le PCM 64-bit floating-point little-endian
DE mulaw PCM mu-law
DE s16be PCM signed 16-bit big-endian
DE s16le PCM signed 16-bit little-endian
DE s24be PCM signed 24-bit big-endian
DE s24le PCM signed 24-bit little-endian
DE s32be PCM signed 32-bit big-endian
DE s32le PCM signed 32-bit little-endian
DE s8 PCM signed 8-bit
DE u16be PCM unsigned 16-bit big-endian
DE u16le PCM unsigned 16-bit little-endian
DE u24be PCM unsigned 24-bit big-endian
DE u24le PCM unsigned 24-bit little-endian
DE u32be PCM unsigned 32-bit big-endian
DE u32le PCM unsigned 32-bit little-endian
DE u8 PCM unsigned 8-bit
DE vidc PCM Archimedes VIDC
相关的编码器宏定义
/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
AV_CODEC_ID_PCM_S16LE = 0x10000,
AV_CODEC_ID_PCM_S16BE,
AV_CODEC_ID_PCM_U16LE,
AV_CODEC_ID_PCM_U16BE,
AV_CODEC_ID_PCM_S8,
AV_CODEC_ID_PCM_U8,
AV_CODEC_ID_PCM_MULAW,
AV_CODEC_ID_PCM_ALAW,
AV_CODEC_ID_PCM_S32LE,
AV_CODEC_ID_PCM_S32BE,
AV_CODEC_ID_PCM_U32LE,
AV_CODEC_ID_PCM_U32BE,
AV_CODEC_ID_PCM_S24LE,
AV_CODEC_ID_PCM_S24BE,
AV_CODEC_ID_PCM_U24LE,
AV_CODEC_ID_PCM_U24BE,
AV_CODEC_ID_PCM_S24DAUD,
AV_CODEC_ID_PCM_ZORK,
AV_CODEC_ID_PCM_S16LE_PLANAR,
AV_CODEC_ID_PCM_DVD,
AV_CODEC_ID_PCM_F32BE,
AV_CODEC_ID_PCM_F32LE,
AV_CODEC_ID_PCM_F64BE,
AV_CODEC_ID_PCM_F64LE,
AV_CODEC_ID_PCM_BLURAY,
AV_CODEC_ID_PCM_LXF,
AV_CODEC_ID_S302M,
AV_CODEC_ID_PCM_S8_PLANAR,
AV_CODEC_ID_PCM_S24LE_PLANAR,
AV_CODEC_ID_PCM_S32LE_PLANAR,
AV_CODEC_ID_PCM_S16BE_PLANAR,
AV_CODEC_ID_PCM_S64LE = 0x10800,
AV_CODEC_ID_PCM_S64BE,
AV_CODEC_ID_PCM_F16LE,
AV_CODEC_ID_PCM_F24LE,
AV_CODEC_ID_PCM_VIDC,
MP3转码为PCM
ffmpeg -i "C:\Users\admin\Music\王备 - 似水柔情.mp3" -f f32le -ac 1 -ar 8000 pcm_f32le_ac1_ar8000.pcm
-f 指定输出PCM的采样位深
-ac指定输出PCM的声道个数
-ar指定输出PCM的采样频率
ffplay播放
一般情况下很少有PCM音频文件,因此可以采用上面的FFmpeg指令,生成一个PCM音频文件,然后进行播放测试
播放pcm原始音频数据
ffplay -f s16le -ac 2 -ar 44100 pcm_s16le_ac2_ar44100.pcm
ffplay -f f32le -ac 1 -ar 8000 pcm_f32le_ac1_ar8000.pcm
ffplay -i file.g711a -f alaw -ac 1 -ar 8000
ffplay -i file.g711u -f mulaw -ac 1 -ar 8000
-f:指定pcm数据的格式,s16se(signed 16 bits little endian, 有符号 16 位小端)
ac:指定音频声道数量
ar:指定音频采样频率
音视频流媒体开发【二十六】ffplay播放器-音频输出和音频重采样 - 简书 (jianshu.com)