FFmpeg在libavfilter模块提供音视频滤镜。所有的音频滤镜都注册在libavfilter/allfilters.c。我们也可以使用ffmpeg -filters命令行来查看当前支持的所有滤镜,前面-a代表音频。本篇文章主要介绍音频滤镜,包括:混音、静音填充、哈斯效应、合唱效果、均衡器、iir与fir滤波器、低通滤波器、带通滤波器、高通滤波器、变速变调、音量调节、静音检测。

关于音频滤镜的详细介绍,可查看官方文档:音频滤镜。上半部分的音频滤镜,可查看:音频滤镜介绍(上)。

1、amerge

合并,把两个或多个音频流合并到一个多通道的输出流。假如输入声道布局是交错的,那么输出声道布局相应地设置,声道根据需要进行重新排序。相反,假如输入声道布局不是交错的,那么先是第一个输入流的所有声道,然后是第二个输入流,依次类推。

比如合并两个音频流,参考命令如下:

ffmpeg -i one.mp3 -i two.mp3 -filter_complex [0:a][1:a]amerge=inputs=2[aout] -map [aout] out.mp3

2、amix

混音,把所有输入音频流混合成单个音频流。该滤镜仅支持浮点采样格式。如果是整型采样格式,会自动转换成浮点采样格式。参数选项如下:

  • inputs:输入音频数,默认为2
  • duration:混音后的音频时长
  • longest:使用最长的输入流时长(默认)
  • shortest:使用最短的输入流时长
  • first:使用第一个输入流时长
  • dropout_transition:过渡时间,默认为2秒
  • weights:每个音频流的占比权重,默认所有音频流权重相同
  • normalize:是否开启归一化,默认开启

混音代码位于libavfilter/af_amix.c,核心代码如下:

// 从FIFO队列读取若干采样数据,然后混音,写到输出缓冲区
static int output_frame(AVFilterLink *outlink)
{AVFilterContext *ctx = outlink->src;MixContext      *s = ctx->priv;AVFrame *out_buf, *in_buf;int nb_samples, ns, i;if (s->input_state[0] & INPUT_ON) {nb_samples = frame_list_next_frame_size(s->frame_list);for (i = 1; i < s->nb_inputs; i++) {if (s->input_state[i] & INPUT_ON) {ns = av_audio_fifo_size(s->fifos[i]);if (ns < nb_samples) {if (!(s->input_state[i] & INPUT_EOF))return 0;nb_samples = ns;}}}s->next_pts = frame_list_next_pts(s->frame_list);} else {nb_samples = INT_MAX;for (i = 1; i < s->nb_inputs; i++) {if (s->input_state[i] & INPUT_ON) {ns = av_audio_fifo_size(s->fifos[i]);nb_samples = FFMIN(nb_samples, ns);}}if (nb_samples == INT_MAX) {ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts);return 0;}}frame_list_remove_samples(s->frame_list, nb_samples);calculate_scales(s, nb_samples);if (nb_samples == 0)return 0;out_buf = ff_get_audio_buffer(outlink, nb_samples);if (!out_buf)return AVERROR(ENOMEM);in_buf = ff_get_audio_buffer(outlink, nb_samples);if (!in_buf) {av_frame_free(&out_buf);return AVERROR(ENOMEM);}for (i = 0; i < s->nb_inputs; i++) {if (s->input_state[i] & INPUT_ON) {int planes, plane_size, p;// 从FIFO队列读取采样数据av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,nb_samples);planes     = s->planar ? s->nb_channels : 1;plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);plane_size = FFALIGN(plane_size, 16);// 开始混音,判断是float类型还是double类型if (out_buf->format == AV_SAMPLE_FMT_FLT ||out_buf->format == AV_SAMPLE_FMT_FLTP) {for (p = 0; p < planes; p++) {s->fdsp->vector_fmac_scalar((float *)out_buf->extended_data[p],(float *) in_buf->extended_data[p],s->input_scale[i], plane_size);}} else {for (p = 0; p < planes; p++) {s->fdsp->vector_dmac_scalar((double *)out_buf->extended_data[p],(double *) in_buf->extended_data[p],s->input_scale[i], plane_size);}}}}av_frame_free(&in_buf);out_buf->pts = s->next_pts;if (s->next_pts != AV_NOPTS_VALUE)s->next_pts += nb_samples;return ff_filter_frame(outlink, out_buf);
}

混音时,如果是浮点数据调用vector_fmac_scalar函数指针,来自libavutil/float_dsp.h的AVFloatDSPContext结构体一个成员变量。将源数据乘以标量,然后相加到目标矢量:

    /*** Multiply a vector of floats by a scalar float and add to* destination vector.  Source and destination vectors must* overlap exactly or not at all.** @param dst result vector*            constraints: 32-byte aligned* @param src input vector*            constraints: 32-byte aligned* @param mul scalar value* @param len length of vector*            constraints: multiple of 16*/void (*vector_fmac_scalar)(float *dst, const float *src, float mul, int len);

在float_dsp.c源代码中,avpriv_float_dsp_alloc()对函数指针进行赋值:

av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact)
{AVFloatDSPContext *fdsp = av_mallocz(sizeof(AVFloatDSPContext));if (!fdsp)return NULL;fdsp->vector_fmac_scalar = vector_fmac_scalar_c;fdsp->vector_fmul_scalar = vector_fmul_scalar_c;return fdsp;
}

让我们看看vector_fmac_scalar_c()方法的实现:

static void vector_fmac_scalar_c(float *dst, const float *src, float mul,int len)
{int i;for (i = 0; i < len; i++)dst[i] += src[i] * mul;
}

3、apad

填充,将音频流结尾填充为静音。参数选项如下:

  • packet_size:静音数据包大小,默认为4096
  • pad_len:填充为静音的采样数
  • whole_len:指定最少的输出采样数
  • pad_dur:指定填充时长
  • whole_dur:指定最小的输出时长

4、atempo

变速,调节音频播放速度。只接受一个参数atempo,取值范围[0.5, 100.0],默认为1.0。需要注意的是,如果atempo大于2,将会跳过一些采样数据。

音频改为2倍速,参考命令如下:

ffmpeg -i in.mp3 -filter_complex atempo=2.0 out.mp3

5、chorus

合唱,添加合唱效果到音频流。合唱类似于具有短延迟的回声效果,但回声的延迟是恒定的,而合唱则使用正弦波或三角形波调制来改变延迟。因此,延迟的声音听起来会更慢或更快,即延迟的声音会围绕原始声音进行调谐。参数选项如下:

  • in_gain:输入增益,默认为0.4
  • out_gain:输出增益,默认为0.4
  • delays:延迟时间,一般为40ms到60ms
  • decays:衰减系数
  • speeds:设置速度
  • depths:设置深度

6、haas

哈斯,应用哈斯效应到音效中。需要注意的是,这主要作用于单声道信号。将此滤波器应用单声道信号时,会提供方向感,并且转换为立体声。参数选项如下:

  • level_in:输入等级,默认为1
  • level_out:输出等级,默认为1
  • side_gain:侧边增益,默认为1
  • middle_source:中间声源类型,包括以下参数:
  • ‘left’:选择左声道
  • ‘right’:选择右声道
  • ‘mid’:中间立体声道
  • ‘side’:侧边立体声道
  • middle_phase:是否改变中间相位,默认关闭
  • left_delay:左声道延迟,默认为2.05 ms
  • left_balance:左声道均衡,默认为-1
  • left_gain:左声道增益,默认为1
  • left_phase:改变左相位,默认关闭
  • right_delay:右声道延迟,默认为2.12 ms
  • right_balance:右声道均衡,默认为1
  • right_gain:右声道增益,默认为1
  • right_phase:改变右声道相位,默认开启

7、silencedetect

静音检测,检测音频流的静音部分。当该过滤器检测到输入音频音量小于或等于噪声容限值,且持续时间大于或等于检测到的最小噪声持续时间时,认定为静音。参数选项如下:

  • noise, n:噪声容忍值,单位为dB, 默认为-60dB
  • duration, d:设置静音时长,默认为2s
  • mono, m:独立处理每个声道,默认关闭

检测静音的参考命令如下:

ffmpeg -i hello.mp3 -af silencedetect=noise=0.0001 -f null -

输出结果以silence_start开始,silence_end结束,silence_duraition为静音时长:

[silencedetect @ 0000020c67936fc0] silence_start: 268.82
[silencedetect @ 0000020c67936fc0] silence_end: 271.048 | silence_duration: 2.22796

FFmpeg源码分析:音频滤镜介绍(下)相关推荐

  1. FFmpeg源码分析:视频滤镜介绍(上)

    FFmpeg在libavfilter模块提供音视频滤镜.所有的视频滤镜都注册在libavfilter/allfilters.c.我们也可以使用ffmpeg -filters命令行来查看当前支持的所有滤 ...

  2. ffmpeg源码分析-parse_optgroup

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  3. FFMPEG 源码分析

    FFMPEG基本概念: ffmpeg是一个开源的编解码框架,它提供了一个音视频录制,解码和编码库.FFMPEG是在linux下开发的,但也有windows下的编译版本. ffmpeg项目由以下几部分组 ...

  4. ffmpeg源码分析-ffmpeg_parse_options

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  5. ffmpeg源码分析-transcode_step

    本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8 ffmpeg 源码分析系列以一条简单的命令开始,ffmpeg -i a.mp4 b.flv,分析其内部逻辑. a. ...

  6. FFMPEG源码分析(一)

    FFMPEG源码分析(一) ffmpeg之前公司项目中就使用过,但是多停留于应用层面,实现某个功能时,需要哪些结构体以及调用哪些函数.最近想系统的学习一下ffmpeg,于是开始看雷霄骅https:// ...

  7. FFMPEG源码分析(二)

    ffmpeg源码分析之数据流 本文主要介绍ffmpeg的数据流,在ffmpeg中主要分有三个主要用途用于媒体流的解码播放,媒体流的转换(解码之后再编码)和媒体流录制. 媒体流的解码播放 在ffmpeg ...

  8. FFmpeg源码分析-直播延迟-内存泄漏

    FFmpeg源码分析-直播延迟-内存泄漏|FFmpeg源码分析方法|ffmpeg播放为什么容易产生延迟|解复用.解码内存泄漏分析 专注后台服务器开发,包括C/C++,Linux,Nginx,ZeroM ...

  9. 【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍

    [SemiDrive源码分析][X9芯片启动流程]08 - X9平台 lk 目录源码分析 之 目录介绍 一./rtos/lk/ 目录结构分析 1.1 /rtos/lk_boot/ 目录结构分析 1.2 ...

  10. ffmpeg源码分析与应用示例(一)——H.264解码与QP提取

    本文包含以下内容 1.H.264解码流程详述与对应ffmpeg源码解析 2.针对一个应用实例介绍通过修改ffmpeg源码解决问题的方案 具有较强的综合性. 先介绍一下在第二部分中将要解决的实际问题:自 ...

最新文章

  1. L1-003. 个位数统计
  2. GPass:GNOME 暗码治理器
  3. 9.4 均值标准化-机器学习笔记-斯坦福吴恩达教授
  4. ASP.NET MVC分页实现
  5. linux的内核有多小,Linux 内核有小bug?
  6. 转载[POJ题型分类]
  7. mysql 学习笔记03修改表以及其他操作
  8. python基本语法:字典
  9. java中程序执行顺序
  10. 哈夫曼编解码器C语言可运行
  11. 【java学习之路】(java SE篇)002.java SE基础语法
  12. 呈现模式_外汇欧盘:分析师料欧元有望涨至1.15 全球市场呈现轮涨模式
  13. JavaScript 将两个数组合并,且删除重复的值
  14. java员工表代码_基于java+ssh员工考勤管理系统源代码
  15. 销傲销售过程GSP管理系统功能概述
  16. 2.3.1 TextView(文本框)详解
  17. sd卡与FAT32文件系统
  18. ChatGPT 从入门到精通
  19. R星安装不完全无法载入social club(错误码:1)解决办法
  20. 字节跳动问我计算机网络,我一口气全答对!

热门文章

  1. HiJson 百度网盘下载
  2. 免费sip虚拟服务器,VOIP服务器软件Sip服务器miniSIPServer
  3. linux i3 桌面,Linux 桌面平铺管理器 - i3wm
  4. Android 动态壁纸
  5. AWG#线规及其载流能力和电阻值
  6. 基于Python的指数基金量化投资 - 指数投资技巧(一)定期定额
  7. js调用html文件上传,JavaScript里的文件上传API
  8. Linux C/C++之TCP / UDP通信
  9. eeglab新建电极位置并保存为文件
  10. 基于贝叶斯网络模型的自适应测评