《ffmpeg basics》中文版 -- 16.数字音频

16.数字音频

​ 术语数字音频和术语数字视频类似,数字视频是一种用于处理和显示可移动图像的技术,而数字音频则是处理声音。数字音频是一种可以使用 PCM(pulse-code modulation:脉冲编码调制)来将声音编码为字节流的技术,它包括捕捉,记录,编辑,编码,复制等多个操作。FFmpeg 支持多种音频格式,如 AAC , MP3 , Vorbis ,WAV , WMA 等。在第二章中我们列出了 FFmpeg 中支持的所有音频格式。

数字音频介绍

​ 由人耳感知到的声音可以被分为声调(tones)和噪音(noises),声调由物质规则的震动产生,噪音则是由不规则的震动产生的。机械振动以压力波的形式通过空气传递到耳膜,并由它转化为神经信号,最后被人"听到",这就是听觉系统。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-twI8rqzi-1578731431919)(./16humanauditory.png)]

音频的量化和采样

​ 由于人类听觉系统的生理限制,我们可以将连续的压力波采用有限的一系列值来描述和代替,然后将这些值转化为数字并保存在电脑中。由于电脑采用二进制,所以常见的音频位深(bit depth)均为2的幂:

在这里插入图片描述
在这里插入图片描述
​ 模拟音频信号就是每隔一个时间单位取一个样本值,然后将这些样本值按时间顺序排列的数据集。常见的取样频率(sample rates)如下表所示:

在这里插入图片描述

音频文件格式

​ 量化并取样后的音频可以用多种格式来保存,下表描述了仅能包含音频的特定文件格式(MP3格式除了音频外也能包含图片):

在这里插入图片描述

​ 关于音频格式和编解码的详细信息,可参阅《格式转换(Conversion Between Formats)》章节。

声音合成

​ 声音由物体围绕某个特定位置的震动产生,通常震动被称为声调,可以用不同振幅和频率的正弦波和余弦波表示:
在这里插入图片描述
​ 特定音高的连续声调可以使用 sin(tone_height*2*PI*t) 来表示,其中 tone_height 表示要表达的音高相对应的频率,单位Hz;PI 是圆周率常量 ;t 表示时间,单位秒。如果想要使用数学表达式来创建声音,我们可以使用 aevalsrc 这个音频源,它的输出可以被保存为一个音频文件。输出音频可以包含多个通道,每个通道都有 3 个可用的变量表达式来描述,细节如下:

在这里插入图片描述

​ 下表包含了从 C1 到 B8 声调的频率,这是以 A4 声调为音调标准的,其频率为 440 Hz,人类可察觉的声音范围为 E2 (男性低音) 到 C6 (女性高音)。

在这里插入图片描述

​ 想要产生 A4 声调的声音,命令如下:

ffmpeg -i lavfi -i aevalsrc=sin(440*2*PI*t) -t 10 noteA4.mp3

立体声和更复杂的声音

​ stereo:立体声

​ 如果想要使用 aevalsrc 音频源来创建多通道声音,我们需要为每一个通道指定其定义表达式,通道之间使用冒号分割,然后跟随两个冒号,最后是通道的布局。可以使用 -layout 选项来布局通道,可用的布局如下:

在这里插入图片描述

​ mono:单声道声音,特指 FC 的一个通道的声音

​ stereo:立体声,特指为 FL + FR 的两个通道的声音

​ 例如,想要创建一个左通道 为 C4,右通道为 C5 的声音,命令如下:

ffplay -f lavfi -i aevalsrc=sin(261.63*2*PI*t):cos(523.25*2*PI*t)::c=FL+FR

用于减压的双耳音调

​ 立体音中有些特殊的类型被称为双耳音调(binaural tones:即左右为两个声调):左右两个声调的频率差为 30 Hz 或者更小,且左右两个声调的频率都必须低于 1000 Hz。通过立体声耳机聆听双耳音调会有一些积极的感官效果,如减轻压力,提高学习效率等对大脑功能有增益效果,当然其实际效果和使用的频率和频率差值有关。我们现在创建一个双耳音调:

ffplay -f lavfi -i aevalsrc=sin(495*2*PI*t):cos(505*2*PI*t)::c=FL+FR

声音的音量设置

​ 声音的音量应小心设置,以免对人耳造成损伤。FFmpeg 提供了 2 中方法来修改音量。第一种是使用 -vol 选项,它接受一个范围在 0~256 的数值,其中 256 为最大值。示例:

ffmpeg -i sound.wav -vol 180 sound_middle_lound.wav

​ 另一种方法是使用 volume filter,详细描述如下:

在这里插入图片描述

​ 例如,我们将声音减到原音量的三分之二,命令如下:

ffmpeg -i music.wav -af volumn=2/3 quiet_music.wav

​ 想要将音量增加 10 分贝,命令如下:

ffmpeg -i sound.acc -af volume=10dB louder_sound.acc

多个声音混合为一个输出

​ 想要混合长度不同的多个声音,并指定转变间隔,我们可以使用 amix filter,描述如下:

在这里插入图片描述

​ 当有多个不同长度的声音混合时,在某个时刻,必然会有一个较短的声音提前结束,此时如果直接结束该输入,会使得声音变化非常的突兀,因此需要一个时间段来过度变化,而不是突然变化,

​ 如下面的命令,将 4 个输入音频混合为了一个,混合后的长度等于输入音频中的最长时长,且在输入声音之间的转化时间为 5 秒:

ffmpeg -i sound1.wav -i sound2.wav -i sound3.wav -i sound4.wav -filter_complex amix=inputs=4:dropout_transition=5 sounds.wav

将立体声降为单声道,环绕音降为立体声

​ 想要将多声道的声音降低通道,如立体声降低为单声道,我们可以使用 pan filter,其详细描述如下:

在这里插入图片描述

​ ch_name:表示输出的某一个channel,可以用名称或者通道数来指定;in_name:表示输入的某个channel;gain:表示增益,也就是一个系数,或者音量。而channel_def定义了如何使用in_name指定ch_name。layout指定我们需要输出的channel,而channel_def则具体指定某个channel。

​ 以下是几个降低通道的示例:

  • 使用相同的音量,将左通道和右通道混合:
ffmpeg -i stereo.wav -af pan=1:c0=0.5*c0+0.5*c1 mono.wav

或者:

ffmpeg -i stereo.wav -af pan=mono mono.wav
ffmpeg -i stereo.wav -af pan=1 mono.wav
  • 左右通道混合,但左通道的音量更大一些:
ffmpeg -i stereo.wav -af pan=1:c0=0.6*c0+0.4*c1 mono.wav
  • 左右通道混合,但右通道的音量更大一些:
ffmpeg -i stereo.wav -af pan=1:c0=0.3*c0+0.7*c1 mono.wav

​ 如果不使用 pan filter ,我们也可以降低声音的通道,当源音频文件的通道数大于 2 时,我们可以使用 -ac[:stream_specifier] 选项使用一个数字来指定输出的通道值:

ffmpeg -i 5_1_surround_sound.wav -ac 2 stereo.wav

​ 当我们想在降低声音通道的操作中添加额外的参数,那么我们就只能使用 pan filter。下一个例子自动可以将 3通道,4通道,5通道或7通道的音频降为2通道的立体声:

ffmpeg -i surround.wav -af pan=stereo:FL<FL+0.5*FC+0.6*BL+0.6*SL:FR<FR+0.5*FC+0.6*BR+0.6*SR stereo.wav

简单音频分析

​ ashowinfo filter 可以为每一个输入的音频帧提供相关的细节信息,它会为每个音频帧输出一行信息,其中最多可以有 10 个参数信息,ashowinfo filter 的描述如下:

在这里插入图片描述

​ 由于 ashowinfo 的输出可能会非常长,因此我们应该使用 -report 选项将输出保存到文件中,例如:

ffmpeg -report -i audio.wav -af ashowinfo -f null /dev/null

​ 一个 10 秒长,44100 Hz 编码的的立体声,其信息输出如下图所示:

在这里插入图片描述

为使用耳机收听而调整音频

​ 可以使用 earwax filter 来增强输入音频的立体声效果,其描述如下:

在这里插入图片描述

​ 例如,想要提高文件 music.mp3 的立体效果,我们可以使用命令:

ffmpeg -i music.mp3 -af earwax -q 1 music_headphones.mp3

使用 -map_channel 选项来修改音频

​ -map_channel 选项可以用于修改多个音频参数,其语法如下:

-map_channel [in_file_id.stream_spec.channel_id|-1][:out_file_id.stream_spec]
  • 如果 out_file_id.stream_spec 参数未设置,则指定的音频channel将映射到输出中所有的音频流中
  • 如果使用了 -1 而不是 in_file_id.stream_spec.channel_id,映射为一个无声通道
  • -map_channel 选项的顺序决定了输出流中对应的channel的顺序,输出的通道布局是从映射的通道数计算出来的(单声道使用一个 -map_channel,立体声使用两个 -map_channel,以此类推)。
  • -ac 选项可以和 -map_channel 选项配合使用,当输入和输出的通道布局不匹配时,我们就可以使用这个组合来设置通道的增益水平(例如,两个 ”-map_channel“ 选项和一个 ”-ac 6“ )。

交换输入立体声的音频通道

​ 如果我们想要将输入立体声音频文件的左通道和右通道交换,命令如下:

ffmpeg -i stoero.mp3 -map_channel 0.0.1 -map_channel 0.0.0 ch_switch.mp3

将立体音拆分为两个独立的流

​ 将一个两通道的立体音输入拆分为两个独立的流,然后编码到一个输出文件中(由于 MP3 仅能包含一个音频流,因此输出格式必须为 ACC,OGG,WAV等),命令如下:

ffmpeg -i stereo.mp3 -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 output.acc

将输入立体音的一个通道静音

​ 想要将输入的某个通道静音,我们可以在 -map_channel 选项中使用 -1 值。例如,想要静音立体声中的第一个通道,命令如下:

ffmpeg -i stereo12.mp3 -map_channel -1 -map_channel 0.0.1 mono2.mp3

将2个音频流混合为一个多通道的流

​ 我们可以使用 amerge filter 来将两个音频流混合为一个多通道的流,amerge 有一个参数 inputs,它用来指定输出文件的数量,默认值为 2 。所有的输入文件必须使用相同的取样频率和文件格式编码。例如,想要混合两个单通道的文件为一个立体声流的文件,命令如下(总时长为较短输入的时长):

ffmpeg -i mono1.mp3 -af amovie=mono2.mp3[2];[in][2]amerge stero.mp3

音频流的前进缓冲顺序控制

​ 两个输入音频流的同步,可以使用 astreamsync filter 来控制,它有一个参数,它的值由几个变量组成的可选表达式指定。表达式的默认值是 t2-t1 ,意思是总是使用更小的时间戳来推进音频流。

在这里插入图片描述

H&A
发布了7 篇原创文章 · 获赞 4 · 访问量 818

猜你喜欢

转载自blog.csdn.net/qq_34305316/article/details/103937974