JHHK

欢迎来到我的个人网站
行者常至 为者常成

【MJ】12_音频重采样

参考:【秒懂音视频开发】12_音频重采样

本文是上面文章的摘要,只用于自己快速浏览.

目录

补充

一. 音频格式

SDL中音频格式的表示解析:
AUDIO_S16LSB
AUDIO_U16LSB
AUDIO_U16MSB
AUDIO_S16MSB
AUDIO_F32MSB

S:有符号
U:无符号
F:浮点类型
16:16个Bit位
32:32个Bit位
LSB(Least Significant Bit\Byte) 代表小端存储
MSB(Most Significant Bit\Byte) 代表大端存储

FFmpeg中音频格式的表示解析:
AV_SAMPLE_FMT_S16LE
AV_SAMPLE_FMT_U16LE
AV_SAMPLE_FMT_S16BE
AV_SAMPLE_FMT_U16BE
AV_SAMPLE_FMT_S32LE
AV_SAMPLE_FMT_S32BE

S:有符号
U:无符号
16:16个Bit位
32:32个Bit位
LE(Little End) 代表小端存储
BE(Big End) 代表大端存储

AV_SAMPLE_FMT_S16
AV_SAMPLE_FMT_S32
AV_SAMPLE_FMT_FLT

简写模式:
S16:S16LE
S32:S32LE
FLT:F32LE待定

二. 对象释放

释放对象时为什么要传入一个指针变量地址呢?

我们先来看下,销毁一个对象的流程

//创建一个对象
LXYTest * test = new LXYTest();
//销毁对象
delete test;
//指向清空,避免内存非法访问
test = nullptr;

那么当我们写一个函数时,应该怎么做呢?

void freeTest(LXYTest** ptr){
    delete *ptr;
    *ptr = nullptr;
}

//调用
freeTest(&test);

三. 关于指针

看下变量的意义

//变量a对应一个4字节大小的内存,内存内放置的内容是10
int a = 10;

//取出a对应的内存中的内容10
int b = a;

//将20放入a对应的内存中
a = 20;

指针解析

//假如a的变量地址是:0x11
//存放的内容是10
int a = 10;

//假如b的变量地址是:0x22
//b内存放的内容是:0x11
int * b = &a;

//取出b指向的内存空间的内容:10
int c = *b;

//将20放入b指向的内存空间
*b = 20;

两个**指针分析

什么叫音频重采样

音频重采样(Audio Resample):将音频A转换成音频B,并且音频A、B的参数(采样率、采样格式、声道数)并不完全相同

音频A的参数
采样率:48000
采样格式:f32le
声道数:1

音频B的参数
采样率:44100
采样格式:s16le
声道数:2

为什么需要音频重采样

这里列举一个音频重采样的经典用途。

有些音频编码器对输入的原始PCM数据是有特定参数要求的,比如要求必须是44100_s16le_2。但是你提供的PCM参数可能是48000_f32le_1。这个时候就需要先将48000_f32le_1转换成44100_s16le_2,然后再使用音频编码器对转换后的PCM进行编码。

命令行

通过下面的命令行可以将44100_s16le_2转换成48000_f32le_1。

ffmpeg -ar 44100 -ac 2 -f s16le -i 44100_s16le_2.pcm -ar 48000 -ac 1 -f f32le 48000_f32le_1.pcm

编程

音频重采样需要用到2个库:
swresample
avutil

音频重采样流程

  1. 创建输入缓冲区:输入声道数量,输入样本格式,定义的样本数量,来决定输入缓冲区大小
  2. 创建输出缓冲区:输出声道数量,输出样本格式,根据采样率换算出的样本数量(向上取整),来决定输出缓冲区大小
  3. 创建并初始化重采样上下文:(输入,输出)采样率,声道数,样本格式
  4. 重采样:读取文件数据重采样时,数据会从输入文件读取到输入缓冲区再到输出缓冲区,然后再写入输出文件
  5. 检查残留样本:输出缓冲区数据会有残留,需要将残留的部分转入到输出文件
  6. 释放资源:释放输入输出缓冲区(**指针释放要注意),释放采样上下文

注意:
PCM1 -> PCM2 -> PCM3 -> PCM4 进行一轮重采样
其中 PCM1 PCM2 PCM3 声道数,采样率,样本格式不完全相同
PCM1的声道数,采样率,样本格式与PCM4完全一样
PCM4文件会略大于PCM1,原因就在于第二步的向上取整.


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.