音视频从入门到精通——FFmpeg之swr_convert音频重采样函数分析

音频重采样

音频解码出来之后一般不能直接播放,要经过重采样。有点类似像素图像格式的转换。
在这里插入图片描述

swr_alloc函数

/**
 * Allocate SwrContext.
 *
 * If you use this function you will need to set the parameters (manually or
 * with swr_alloc_set_opts()) before calling swr_init().
 *
 * @see swr_alloc_set_opts(), swr_init(), swr_free()
 * @return NULL on error, allocated context otherwise
 */
struct SwrContext *swr_alloc(void);

swr_alloc函数,分配SwrContext

swr_alloc_set_opts函数

/**
 * Allocate SwrContext if needed and set/reset common parameters.
 *
 * This function does not require s to be allocated with swr_alloc(). 
 * On the other hand, swr_alloc() can use swr_alloc_set_opts() 
 * to set the parameters on the allocated context.
 *
 * @param s               existing Swr context if available, or NULL if not
 * @param out_ch_layout   output channel layout (AV_CH_LAYOUT_*)
 * @param out_sample_fmt  output sample format (AV_SAMPLE_FMT_*).
 * @param out_sample_rate output sample rate (frequency in Hz)
 * @param in_ch_layout    input channel layout (AV_CH_LAYOUT_*)
 * @param in_sample_fmt   input sample format (AV_SAMPLE_FMT_*).
 * @param in_sample_rate  input sample rate (frequency in Hz)
 * @param log_offset      logging level offset
 * @param log_ctx         parent logging context, can be NULL
 *
 * @see swr_init(), swr_free()
 * @return NULL on error, allocated context otherwise
 */
struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
                                      int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
                                      int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
                                      int log_offset, void *log_ctx);

swr_alloc_set_opts函数,设置输入输出参数

swr_init函数

/**
 * Initialize context after user parameters have been set.
 * @note The context must be configured using the AVOption API.
 *
 * @see av_opt_set_int()
 * @see av_opt_set_dict()
 *
 * @param[in,out]   s Swr context to initialize
 * @return AVERROR error code in case of failure.
 */
int swr_init(struct SwrContext *s);

swr_init函数,设置用户参数后初始化上下文。

swr_convert函数

swr_convert()

针对每一帧音频的处理。把一帧帧的音频作相应的重采样

int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, 
const uint8_t **in, int in_count);

参数1:音频重采样的上下文
参数2:输出的指针。传递的输出的数组
参数3:输出的样本数量,不是字节数。单通道的样本数量。
参数4:输入的数组,AVFrame解码出来的DATA
参数5:输入的单通道的样本数量。

音频基础

音频开发主要应用有

1.1 音频播放器,录音机,语音电话,音视频直播应用,音频编辑处理软件,蓝牙耳机、音箱等。

音频开发具体内容有

2.1 音频采集与播放
2.2 音频算法处理(去噪,静音检测,回事消除,音效处理,功放/增强,混音/分离)
2.3 音频编解码和格式转换
2.4 音频传输协议的开发(SIP,A2DP, AVRCP,RTP,RTCP)

音频应用的难点

3.1 延时敏感、卡顿明感、噪声抑制、回声消除、静音检测、混音算法等。

音频开发基础概念有

4.1 采样率,采样是从模拟语音信号转数字信号的过程,所有的模拟信号都需要通过采样转为可以表示的数字信号。目前44100Hz是唯一可以保证兼容所有Android手机的采样率。

4.2 奈奎斯特理论:采样频率不低于音频信号最高频率的两倍,就可以做到无误还原原始的声音。通常人耳能听到的20HZ-20KHZ的声音,为了保证不失真,采样频率应该在40KHZ以上。

4.3 量化精度(位宽),每一个采样点,都需要一个数值来表示大小,这个大小可以是4bit,8bit,16bit… 位数越多,表示越精细,声音质量就越好,当然,数据量也成倍增大。ENCODING_PCM_16BIT是可以保证兼容所有Android手机的。
4.4 声道数,音频可以从不同的音频源采集并输出到不同的扬声器,一般表示声音录制时的音源数量或者回放时相应的扬声器数量。常见有单身道mono及双声道stereo。

4.5 音频帧,音频数据和视频帧不一样,视频帧就是一张图像,音频数据是流式结构,本身没有明确的一帧的概念,只是为了音频算法处理传输方便,约定2.5ms~60ms为单位的数据量为一帧音频。这个时间为采样时间。AndioRecord内部的音频缓冲区大小不能低于一帧音频帧的大小。一帧音频帧大小:int size = 采样率x位宽x采样时间x通道数。AudioRecord类提供了一个帮助我们确定缓冲区大小的函数,int getMinBufferSize(int sampleRateInHz, int channelConfig,int audioFormat)。假设某双通道音频信号采样率为8k,位宽16bit,20ms一帧的采样时间。则一帧数据的大小为:size = 8000x16x0.02x2 = 640byte(字节)

常见音频编码方式

5.1 A/D需要采样和量化,对应上面提到的采样率和量化宽度。量化的过程被称为编码,根据不同的量化策略,有不同的编码方式,常见有PCM,ADPCM。这些数据代表了无损的原始数字音频信号,添加一些文件头信息,就可以存储为wav文件了。

5.2 获取不同手机终端的编解码分辨率,可以通过adb工具获取/system/etc/media_codecs.xml文件。

常见音频压缩格式

原理:因为有冗余信息,所以需要压缩
6.1 频谱掩蔽效应:人耳能察觉到的频率范围为20hz-20khz,在这个频率范围之外的音频信号属于冗余信号。

6.2 时域掩蔽效应:当强音信号和弱音信号同时出现时,弱信号会听不到,因此此时弱音信号也属于冗余信号。

Android VoIP 相关的开源应用有
7.1 Imsdroid,sipdroid,csipsimple,linephone,WebRTC等。

音频算法处理的开源库有

8.1 Speex,ffmpeg,webrtc

Android 提供音频相关的API

9.1 音频采集:MediaRecoder,AudioRecord
AudioTrack 提供了两种播放模式,一种是static方式,一种是streaming方式,前者需要一次性将所有数据都写入播放缓冲区,简单高效,通常用于铃声播放,系统提醒的音频片段,后者需要按照一定时间间隔不断写入音频数据,理论上可以任何音频播放的场景。

9.2 音频播放:SoundPool,MediaPlayer,AudioTrack

9.3 音频编解码:MediaCodec

9.4 NDK API:OpenSL ES

音频开发的延时标准

10.1 对于高质量语音可以接受延时为300ms,一般而言,如果时延在300~400ms,通话的交互性比较差,但还可以接受,时延大于400ms时,则交互通信非常困难。

参考

SwrContext重采样结构体–swr_alloc()、swr_init()、swr_free()
FFmpeg音频重采样API(libswresample)

音频通道数、采样频率、采样位数、采样个数(样本数)的概念及计算一帧音频的大小、每秒播放的音频字节大小、一帧的播放时长、音频重采样

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值