音频重采样初步分析

音频重采样:

改变音频的 sample rate(采样率)、 sample format(采样格式)、channel layout(通道布局)等参数,使之按照我们期望的参数输出。

相关参数解析:

采样率:采样设备每秒抽取样本的次数
采样格式及量化精度(位宽):
每种音频格式有不同的量化精度(位宽),位数越多,表示值就越精确,声音表现自然就越精准。
FFMpeg音频格式如下:
enum AVSampleFormat {
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
    AV_SAMPLE_FMT_FLT,         ///< float
    AV_SAMPLE_FMT_DBL,         ///< double

    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
    AV_SAMPLE_FMT_FLTP,        ///< float, planar
    AV_SAMPLE_FMT_DBLP,        ///< double, planar
    AV_SAMPLE_FMT_S64,         ///< signed 64 bits
    AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar

    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};
音频数据在声道中存储方式:

分片(plane)和打包(packed)

以双声道为例,
  带P(plane)的数据格式在存储时,其左声道和右声道的数据是分开存储的,
左声道的数据存储在data[0],右声道的数据存储在data[1],每个声道的所占用的字节数为linesize[0]和linesize[1];
  不带P(packed)的音频数据在存储时,是按照LRLRLR...的格式交替存储在data[0]中,
linesize[0]表示总的数据量 。上面ffmpeg音频格式源码有表明。
声道分布(channel_layout)
AV_CH_LAYOUT_STEREO(双声道)定义为:
#define AV_CH_LAYOUT_STEREO (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)

AV_CH_LAYOUT_SURROUND(三声道)定义为:
#define AV_CH_LAYOUT_SURROUND
(AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)
音频的数据量
⼀帧音频的数据量(字节)
=channel数 * nb_samples样本数 * 每个样本占用的字节数(上面提到的枚举AVSampleFormat)
如果该⾳频帧是S16P格式的PCM数据,包含1024个样本,双声道,那么该⾳频帧包含的⾳频数据量是
2*1024*2=4096 Byte

AV_SAMPLE_FMT_DBL : 2*1024*8 = 16384 Byte
音频时间计算
以采样率 44100hz为例,每秒抽取样本数为44100,一帧样本数为1024,
一帧播放时间(转为毫秒)就为 1024*1000/44100 =  23.21995464852608 ≈ 23.2 
精度损失了0.011995464852608ms,如果累计10万帧,误差>1199毫秒,
如果有音视频同步的问题。 如果按着23.2去计算pts(0 23.2 46.4 )就会有累积误差。
采样率转化中样本数的变化
由于每帧播放时间(1024*1000/44100 =  23.21995464852608)不变

44100Hz采样率                                                48000Hz
AV_SAMPLE_FMT_FLTP  			 --转化后->			       	AV_SAMPLE_FMT_FLTP
1024样本数                                                   1115(向上取整)

1024/44100 *48000 = 1,114.557823129252  ->向上取整 1115 
函数swr_convert内部会缓存,这一次输出可能为1114 ,下一次为1115,***1115为输出最大采样点数***。

相关api分析

音频缓冲区——AVAudioFifo

AVAudioFifo是FFmpeg提供的一个先入先出的音频缓冲队列.
单位为样本数并非字节数
支持多通道的格式,不管是planar还是packed类型。
当写入一个已满的buffer时会自动重新分配内存。

av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples);
将数据写入AVAudioFifo ,如果可用的空间小于传入nb_samples参数AVAudioFifo将自动重新分配空间。

int av_audio_fifo_size(AVAudioFifo *af);
返回可用于读取的采样数量

int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) av_const;
根据时间,输入输出采样率,输入样本数算出输出样本数

int64_t swr_get_delay(struct SwrContext *s, int64_t base);
计算缓存中剩余采样点数

int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
                                const uint8_t **in , int in_count);
转换并返回成功转换采样点数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值