ReplayGain在UPnP media server中的应用和补遗

UPnP media server是个挺有用的东西。在PC端配合一个功能非常全面的foobar2000插件——foo_upnp,安卓端配合foobar2000 Mobile或是BubbleUPnP,即可轻松实现包括但不限:用手机播放电脑里的媒体库,用手机当电脑的音响用(呃延迟没测过,估计只够听歌),用手机控制电脑播放器,以及前面的全部反过来控制等功能。当然,最理想的情况是把media server设在诸如NAS之类的设备上,但是就我个人来说,最常用的应用场景是躺在床上耳机插手机听电脑的媒体库/播放列表。

既然前一段时间折腾了那么就RG,这也得用上不是。让我们先仔细研究一下foobar2000那边的server的profile设置。

qq%e5%9b%be%e7%89%8720170220192532

另外为了便于测试,将Basic Settings里设成始终使用默认profile和关闭增加兼容性的额外流:

qq%e6%88%aa%e5%9b%be20170220193855

可以看到大抵来说,有这么几种streaming的方案:源文件直出,转码为MP3,解码为WAV。

直出最好理解,就是在http上host对应的文件而已。直出可以保有原始文件的所有metatag,自然也就包括RG信息;这样,在移动端使用支持RG的客户端时(这里就是foobar2000 mobile了),就会读取到信息进行响度调整。

但是直出的局限性非常大。foobar2000 mobile支持的格式非常有限。TAK这种就不用说了,自然也不支持任何音频文件+cue的类型。不过倒也不会播不了,只是sever会自动无条件帮你转成WAV。最吊诡的是,像FLAC这种明明是支持的格式(即,你把歌曲拷贝到手机里是能放的),有时候会在foobar2k mobile那边出现播放列表里完全看不到的现象(不能稳定重现。与之相对,第三方的BubbleUPnP则很稳定不会有这个问题)。

既然直出这条路不行,那就只能转码或者解码了。介于局域网带宽对于音频来说完全不是问题,自然选择音质更好的WAV,也避免了二次压缩的问题。不过,转码/解码之后有一个问题,就是RG信息完全丢失。哪怕是转码成MP3也是一样。还好,在下面那个Audio processing里,和Converter(转码器)一样,可以设置转码/解码时的处理。注意这里既然叫processing那自然是硬编码进去,而不是靠RG信息。所以foobar2000 mobile端会识别成无RG信息,调整那边相应的RG设置时要注意(我则是完全关闭)。

哦从图中可以看到,你可以设置规则对不同文件类型设置不同的转码规则(例如有些转,有些直出等等)。但是没啥卵用,因为你一旦开启了processing,所有的都会被强制转一遍mp3/WAV,所以还是死了这条心。

这里又是和上一篇文章中提到的普通用电脑回放时一样,面对一个抉择:是选择全部降低到和RG目标响度一样的响度(即:较低的响度),还是全部增益到和“新歌”一致的一个比较高的响度。这里还是选择了前者,因为毕竟那样对音质的保存是最完整的,而且主要用耳机听歌的话也不用担心有输出不足的问题。具体来说,就是在Processing里开启apply RG,同时对无RG信息的歌曲(主要是响度大的新歌)加个-9.5 dB的pre-amp。如果还不放心可以再加个Advanced limiter(虽然99%的情况根本不会有任何区别),但是介于Advanced limiter目前有个会把1缩成0.9999的bug,还是别了罢。

当然这种选择下就会有一个问题,那就是和我手机里那些已经转换好的、响度和新歌一个水平的音频文件有冲突。而且因为两者都是无RG信息,也无法靠调整手机端的RG设置中pre-amp来弥补。不过还好我一般其他场合听歌是用Google Music而不是foobar2000 mobile,以后就用fb2k mobile专门听媒体库就是。

多说一句,客户端那边选用foobar2000 mobile而不是BubbleUPnP的原因倒不是fb2k mobile支持RG(毕竟在我的最终配置下也用不到),主要还是foobar2000 mobile支持手机端的last.fm统计插件,虽然BubbleUPnP的界面大概好一万倍(电脑的foobar我觉得还行了,手机那个真的是丑的惨绝人寰)。另外,BubbleUPnP有个很烦的地方就是每次我修改服务器端(我电脑)的UPnP设置那边就必须会自动切断连接,也就是退出所有的远程playlist啥的,我还得重新选,在测试的时候尤其烦。而foobar2000 mobile则是另外一个极端……不但不会断,他还会缓存一部分媒体的地址(其实就是个URL,可以在电脑端或手机端的console里看到),也就是说我切换了设置之后有时候得在那边强制退出一次来让他刷新URL(服务器端这边即使你修改了设置,老设置的URL实际上还是并没有禁用的,依然有效)和播放列表。

screenshot_20170220-193326
客户端(foobar2000 mobile)读取流媒体的log范例

UPnP媒体库播放的响度规格化这事儿到此也就告一段落了。不过,我又回头去想在移动设备播放歌曲的workflow能否有可优化的地方。

如前文所述,我目前在移动设备采用的是“新歌不变,老歌先RG再+9.5dB”的方案,原因是因为这样兼容性最好,对没有RG支持的播放器也能完美播放,而且不会有输出太低的问题(我手机插车上听,即使在这种设置下都几乎要开到最大音量才行了,如果全部都低9.5dB那可调整的余地就太小了)。当然最大的问题就是+9.5dB导致的超过full scale引起的削波问题。

解决方案上次也说过,就是在转换时再用DSP加一层Advanced limiter,把超出的部分动态调整到1以下。不过由于犹豫会对音乐的完美呈现造成影响(毕竟还是部分压缩了动态范围)我之前一直没用。不过最近遇到这么一首歌,一下子就听出削波的问题了(下载链接):

废话一下,歌曲是菊池桃子的「卒業 -GRADUATION-」,个人的五星歌曲。算是无数好听的叫“卒业”的歌曲之一(其他的还有尾崎豊的,斉藤由貴等等)。菊池桃子天使般的声线在这歌里得到完美的体现。咳跑题了。

这歌的问题在于动态范围极大,在我的传统转换设置下,自然会溢出full scale很多,事实上,其peak达到了1.40(+2.93 dBFS)之高。从1:00左右开始,就会疯狂爆音,用手机+耳机听时最明显。因此,Advanced limiter就是非常必要的了。我对比了下开启Advanced limiter的版本和原版,完全听不出区别(毕竟音量大于1的部分只是极小的spike,频段可能更不是人耳敏感的部分),可见这个limiter的效果比起一般的动态压缩要好得多,也解除了我之前的一大顾虑。

不过在研究过程中我发现一个有趣的事实:AAC(m4a)这个格式居然可以保存大于1的数值!也就是说,我上面发这个+过9.5dB的音频文件,其实并没有损失任何信息或者削波——超过FS的1.4的peak也完整地记录在了音频中。这说明了什么呢?如果你的播放流程在输送到DAC之前有足够的衰减处理(例如软件中的波形层面的音量降低,但包含音响上的Analog的音量旋钮),又或者你的DAC/Analog设备足够专业,留有headroom支持超过1的波形,其实并不会产生削波/爆音。对应到电脑,foobar2000里的volume就是个不错的例子(但是别忘了上文提到的Win7的自带的limiter适用过早的bug,所以避免);对应手机端,根据我的观察,至少安卓系统的音量是不行的(不过安卓的音频处理一直都臭名昭著):如果仅仅靠调整系统的媒体音量,该爆音的还是爆(不清楚安卓的系统音量具体原理是数字上衰减波形还是模拟级)。不过,foobar2000 mobile中有个单独的volume设置,通过那个,或者里面带的RG设置的pre-amp,可以做到同响度情况下(即先用foobar2000 mobile的音量降低几个dB,再在系统音量里稍微开大一点达到同样响度)完美无爆音播放上面那个m4a文件。

不过这个用起来其实也有颇多不便:第一个不便是foobar2000 mobile的音量设置……他有bug。每次切歌,音量就会回归到0dB,即使界面里显示的还是你的设置。另外还是上面说的问题了,如果你降了几个dB,那输出不够这老问题又来了。所以,我最终还是经过权衡选择了转换时选择高响度水平+Advanced limiter的方案。当然还有第三个方案:转换时不加Advanced limiter(利用m4a的特性保留超过1的数值),但在播放时靠foobar2000 mobile自带的DSP即时加。这样可以最大限度保存动态范围,以后这些mp4拷贝到电脑上听时还可以还原。我现在还在想要不要全面转成这样——因为如果这么做,就表示了我就锁死只能用foobar2000 mobile当手机播放器了,这方面有点犹豫。

前面说了AAC(m4a)可以保存高于full scale的数值,那相对地WAV、FLAC和APE就不行了,如果你转换过程中增益到超过1,最终出来的文件会被削波到1。当然FLAC/APE之类的是为了完美呈现WAV而故意这么设置的吧,大概。MP3则比较奇怪,还是上面那个歌,转换之后会出来个peak为1.075的玩意…大概和MP3算法有关吧。另外每个的平均响度也会细微的差别,理论上来讲很自然AAC会高一些(毕竟没削波),虽然差别很小就是了。

qq%e6%88%aa%e5%9b%be20170221233307
利用RG扫描来查看peak和平均响度。因为Gain是负值,所以绝对值越大说明响度越大。音频全部通过原始wav文件+硬编码进(RG+增益9.5dB)的方式逐一生成

所以很显然地,如果你是转成了FLAC之类的已经会直接削波的格式,即使上面那个很复杂的操作也没法拯救你这音频了,怎么放都会爆音,万万要避免。

嗯,最后附一个几种流程的图示吧。三脚猫ps功夫不要笑话(点击大图)。

blog.png

上面的是最终响度=RG目标响度的workflow,优点是基本无损,缺点是输出比较低。目前我在电脑和UPnP媒体库输送到手机两种回放方式时使用。可以看到新歌直接降低-9.5dB(图里写成9了…),老歌直接RG,两者会获得一个相对一致的响度,同时不破坏老歌的动态范围。注意这里的-9.5dB和RG都是纯粹回放时加的,原始音频是不经过修改的。

下面的是方法2,即最终响度=新歌平均响度的workflow。我在转换歌曲到单独m4a文件时使用此方法。优点是兼容性强,和大多数市面上现成的歌曲文件响度一致;缺点自然是对于高动态的老歌峰值会溢出。为了防止削波,如果是即时回放或转换成支持超过FS的格式(AAC/m4a)时,可以通过再加个digital音量调整拯救(这种情况下就依然无损动态范围),或者如图所示干脆直接最后加个可选的Advance limiter进去(可以是转换时的硬编码,可以是回放的DSP)。对于不支持超过FS的音频格式,这大概是唯一可以接受的转换方案)。

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s