一、概述
本文分析 FFmpeg af_volume 的实现
二、af_volume的作用及基本原理
af_volume的作用是调整音频的音量,基本原理是PCM数据乘于某个系数,就达到了调整音量的目的
三、在调用ffmpeg程序时使用 af_volume
减半音量:
ffmpeg -i input.mp3 -af "volume=0.5" output.mp3
ffmpeg的表达式解析和计算支持将“volume=0.5”写作“volume=1/2”(不会当成整数相除,否则有除0的情况)或“volume=-6.0206dB”(负数)音量增加50%:
ffmpeg -i input.mp3 -af "volume=1.5" output.mp3
“volume=1.5”可以写作“volume=3.5218dB”(正数)
上面的-6.0206
是怎么计算的呢?
pow(10, -6.0206 / 20)
约等于0.5
同样的对于3.5218
,pow(10, 3.5218 / 20)
约等于1.5
音量增加8分贝:
ffmpeg -i input.mp3 -af "volume=8dB" output.mp3
如果带上 dB 后缀将直接增加或减少指定分贝。正数是增加,负数是减少。实际上传入 dB 值 FFmpeg 会转换成比例值
四、源码分析
af_volume源码位于
ffmpeg/libavfilter/af_volume.c
分析 filter一般从 static int filter_frame(AVFilterLink *inlink, AVFrame *in) 函数入手
如果音量参数是以 dB 为单位,在运算时会转换为比例
五、C#简单实现
/// <summary>
/// 按分贝增加音量。支持 S16LE 格式。
/// </summary>
/// <param name="raw"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="dB">正数增加,负数减少</param>
public static void IncreaseDecibel(byte[] raw, int offset, int length, double dB)
{
if (dB == 0) return;
var scaleFactor = Math.Pow(10, dB / 20);
SetVolume(raw, offset, length, scaleFactor);
}
/// <summary>
/// 按比例设置音量。支持 S16LE 格式。
/// </summary>
/// <param name="raw"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <param name="factor">大于1增加音量,小于1减小音量</param>
public static void SetVolume(byte[] raw, int offset, int length, double factor)
{
if (factor == 1) return;
var numberOfSamples = length / sizeof(short);
for (var i = offset; i < numberOfSamples; i++)
{
var temp = (int)(BitConverter.ToInt16(raw, i * sizeof(short)) * factor);
temp = temp > short.MaxValue ? short.MaxValue : temp;
temp = temp < short.MinValue ? short.MinValue : temp;
var bytes = BitConverter.GetBytes((short)temp);
raw[i * sizeof(short)] = bytes[0];
raw[i * sizeof(short) + 1] = bytes[1];
}
}
参考资料
// FFmpeg filters官网文档: volume
http://ffmpeg.org/ffmpeg-filters.html#volume
// Calculator dB
http://www.sengpielaudio.com/calculator-db.htm
作者:AIby
链接:http://blog.tubumu.com/2020/11/03/ffmpeg-filters-af-volume/
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。