人类大脑对声音的响应速度和敏感程度非常高。K歌时对人声音轨和伴奏音轨的时间对齐有很强的要求。唱吧资深研发总监 王国腾在LiveVideoStackCon2018大会的分享中详细介绍了手机K歌在混音对齐方面存在的问题,解决方案以及值得探索的方向。LiveVideoStack对演讲内容进行整理。
文 / 王国腾
整理 / LiveVideoStack
大家好,我是王国腾,在唱吧主要负责音视频技术的研发和音频新技术的科研工作。本次将主要为大家介绍手机K歌在混音时间对齐方面存在的问题,常规的工程解决方案以及值得探索的方向。
1、手机K歌简介
手机K歌APP模拟的唱歌过程中两个主要的界面场景,演唱和预览。演唱界面,用户跟随伴奏和提示的歌词完成唱歌,主要生成一股人声的干声。预览界面提供了很多音效的后期处理。包括音准和节奏的校准、特效或预制的混音需求,干声和伴奏的合成预览,甚至是分析人声特点,添加一些动态的音效,做到一键修音。
2、音质的评价标准
声音后处理的效果要如何评价呢?比如一些混音师,他们有时候会说这个声音很顶,不够饱满,然而从工程和科学的角度,我们从几个抽象维度描述音效:还原度,清晰度,区分度,瑕疵的掩盖能力,以及音乐和声音融合度。
还原度是一个比较客观的量化标准,即声音重放质量与原声对比,能够达到怎么样的程度;清晰度形容人声“咬字清晰”,比如说到元音的时候瞬态好不好,说到辅音的时候音量是不是过大或者过小了。如果辅音的音量太大的话,听起来会比较刺耳,如果音量太小的话,会有点像大舌头似的感觉。区分度是我们增加的一个指标,希望用户能够有很多不同的选择。比如说以前在八九十年代的大摇滚的作品,都会做很大的混响,而现在一般都会把这个声音做得比较干,期望将歌手的原音表达更清楚。瑕疵掩盖能力是指即便音准和节奏都正确,但由于个人的音色引起的一些声音处理的问题。比如鼻音比较重的话,在音效处理的时候,我们应该怎样去处理这种瑕疵问题,还有些人唇齿音会比较重,这种问题要怎么处理,是瑕疵掩盖能力。音乐和声音融合度,人声也是宽带信号,在低频上面,谐波会多一些。一段音乐伴奏,它所能覆盖的频段是比较宽的,那么该怎样将这两个声音融合在一起,并且还能清楚的听到人声。而另外一个就是在音乐上面特有的问题,节奏是应该严格对齐的。音准和节奏都是有融合度问题,音准和节奏不准了,听起来会是个跑调的状态。
我们假设人声唱的节奏本身没有问题的话,将人声和伴奏混在一起,如果偏差超过了35毫秒,人耳就会感觉到异常,如果超过50毫秒,就已经是不可接受的了。除此之外,根据我们所做的双盲测试,专家级的耳朵,如果人声比伴奏提前10~15毫秒,或者是比伴奏晚了25毫秒,那么在专家级别人的耳中是有感觉的。总的来说,偏差在35毫秒之内大约有90%的人是没有感受的。在音乐节奏的场景下,人的耳朵会非常敏感。在唱歌时,听到音乐的人本身对节奏会有一个认识,然后会再根据这个节奏唱出自己的声音,一般歌曲的速度稳定,那么唱歌的人也会跟随稳定的速度演唱,由此可见人本身就是无延迟的反馈系统。
3、时间偏移要义
演唱时间偏移主要分成两大类,一类是演唱实时反馈的时间偏移,一类是混音对齐的时间偏移。
演唱实时反馈的时间偏移,主要关注的是演唱时,人声与从耳机反馈回去(实时耳返)的声音之间的实时偏移。这个偏移量一般我们要控制在30毫秒以下,如果在30毫秒以上,人唱歌的时候会受到一些影响;在50毫秒的时候,演唱就会变得非常困难。混音对齐关注的是人声和伴奏能否以对齐的方式混合在一起。
这里介绍一个测试演唱实时反馈的方法。找一个示波器,分别采样麦克风和耳机的声音信号,测试人员可以发出一些比较短促的声音,如敲击或是脉冲。此时示波器上可以看到分别从麦克风采集出来的脉冲与从耳机得到脉冲,通过两个脉冲的时间差就能了解到演唱实时反馈的时间偏移量的大小。
在安卓设备的系统中,各个厂家通常会做一些标识,”low_latency” tag 和”hardware.audio.pro” tag,这两个tag会告诉开发人员,手机的演唱实时反馈偏移量的大小。”low_latency”关注的是在手机中播放一个声音,从需要播放到speaker真正发出声音来,偏移量的大小,一般是在45毫秒以下。而audio.pro则是round trip的时间,通常在20毫秒以内。
造成演唱实时反馈时间偏移的原因分为以下几种:计算性能导致的,系统性能导致的,处理缓冲区导致的时间偏移。
4、安卓手机的优化处理
上图为安卓手机处理声音的示意图,我们从Speaker输入声音,依次经过ADC,总线Bus,Driver,Audio Recorder,应用程序,再转回来整个一圈的处理时间,就是之前提到的round trip 时间。除此之外,在应用层时我们还会将声音信号单独写出一个文件,用来进行后处理。我们希望能将演唱实时反馈的延迟时间控制在30毫秒以内,然而在上述过程中的每个处理步骤都会花掉一些时间,一般情况下,audio flinger可能会花掉10~20毫秒,audio track可能会花掉20~40毫秒。当然,根据设备的不同,实际耗时也会有所不同。
上图展示是我们所做的一种通用的耳返延迟优化方案,将之前上层的audio record和audio Track改成用Open SL来处理。因为Open SL本身是稍微偏底层的接口,这样我们就可以避免掉不少延迟量,并且这个延迟量是相对稳定的。针对相同型号的手机它们的差别并不是很大,并且在不同录制上面的差别也比较小。
上图是现有国产手机时间延迟的解决方案,因为它们手机延迟量的性能指标不满足需求,所以就找到了另外一种方式来绕过这个问题。把一个声音从麦克风录进去,我们只进行半区的处理后保存下来。耳返的声音从手机麦克风添加的旁路芯片直接出来,这种做法的延迟量能够控制的非常小,但芯片处理得到的耳返音效,甚至音量等因素,都很难控制。并且每个厂商会有自己不同的方案,处理的情况也都各不相同,这也大大增加了应用程序上控制的难度。另外,由于安卓手机型号碎片化的问题,需要我们一个一个去做,进展是还是比较缓慢的。但我们仍然可以提供一些经验,比如说我们拿Open SL来处理IO,但是不要处理音效,在旁路添加C++ code来完成。因为Open SL做音效存在较多问题,可能会快15~20毫秒,甚至会出现丢帧。如果我们需要在耳返处理添加实时效果器,一定要保证效果器是实时的,处理本身的固定缓冲延迟尽可能小。当效果器处理是大计算性能的话,我们要考虑让它走一个旁路来完成异步处理,只让湿声去走效果器,干声仍然直接按原路回来,这样的话,我们可以把这个延迟量控制的只是干声的延迟量。在安卓上面可以用一些NEON指令做运算优化,在iOS上面会用DSP做计算的优化。
5、混音对齐要义
混音对齐延迟再细分成4个场景,录放的首帧延迟,演唱中断偏移,效果去处理延迟和歌手演唱误差。歌手演唱误差很好理解,属于自身唱得就不准。录放首帧延迟是指录音文件第一帧时间与伴奏的时间相比较,如果二者在现实中不一致的话,就会产生播放首帧延迟。效果器处理延迟,是指我们在做信号处理的时候,可能会存在一些算法导致的延迟,此外还有一些计算性能导致的延迟。演唱中断偏移则是由一个特殊的功能导致的,是指我们在用手机APP唱歌的时候,是有可能暂停的,比如来个电话、回个微信或者录了一句不满意反复录播,暂停以后继续切回来。这个时候,如果本身就存在录放延迟的话,那么中断一次就会导致再产生一个新的录放首帧延迟,这个延迟累计起来就会是一个比较严重的问题了。有可能前面还是在可控制范围之内,到后面延迟越来越大,就无可奈何了。
那么我们怎么去解决这四类问题呢?分析一下造成首帧延迟的原因,一般设备初始化IO调用的时候会产生延迟,最直接的解决方法就是把音频的录音设备和放音设备相关初始化提前到我们真正开始写文件和开始播放的时候。首帧延迟问题不光存在安卓和IOS里,小程序中的这个问题更严重。如果没有将初始化的时间提前到足够量的话,那么最终混音出来的伴奏和人声的时间差可能达到1~2秒的级别。第二个是减少系统开销,系统开销主要是会造成播放首帧延迟的抖动,形成不稳定的延迟量。而如果是在稳定延迟量的情况下,我们可以通过做一些白名单的方式去解决。现在国产的一些旗舰机,它们的录放首帧延迟基本都是稳定的,甚至有些可以满足30毫秒之内的要求。但也有不少低端机型的延迟量比较大,能够到100~200毫秒。除此之外,现在安卓手机的KTV APP里,都会保留着一个slide bar来进行人肉对齐。
效果器延迟的问题就比较好解决,因为混音对齐是后处理,不受计算性能的影响,我们只要保证它不丢帧,因为每一帧的人声都会对应到每一帧内伴奏上面,所以它的混音对齐不管是计算性能好,还是计算性能差,都一定是从第一帧开始对齐,到最后一帧还是对齐的。我们需要考虑的是,算法延迟量是什么样的,如果算法的延迟量是一个比较稳定且理论上可以计算的话,这件事情就比较简单了。我们最终把人声和伴奏混在一起的时候,把延迟量再找回来就好了。还有一些效果器,可能是不稳定的偏移,只能从算法上做优化,比如说刚才我讲的实时反馈的延迟量,也是可以通过这种方式来解决的,我们在湿声和干声上进行单独的处理。还有一些效果器本身就是一个不稳定偏移量,没有办法做一路湿声,那么我们就只能从算法上尽量把它减小。
再单独说一下演唱中断偏移,比如说暂停或重复上一句,这样都会导致一些演唱中断偏移。其解决方法与上文录放首帧偏移是类似的。需要注意的一点就是用户要暂停这件事情从根本上说并不是要停止录制,而只是想暂停一下,那么我们就可以用静音做播放补偿,如果录放需要快进的话,我们可以再做剪接。
我们在唱歌的时候,如果需要暂停,我们不需要让播放伴奏这一路真正的停止播放,而是插入静音帧。人声这一路,也是同样的处理,因为一旦停止并重新运行就会产生新的录放首帧延迟。如果选择静音,我们只需要在最后混音的时候,严格减去相同的静音数据就可以完成同步。
人声在K歌的时候是一个贴唱的过程。贴唱就是指我们现在已经有一个伴奏,人声根据伴奏逐句演唱。人声演唱时包含以下特点:辅音提前,元音对齐;伴奏速度基本稳定;节奏型出错少,速度型出错多。那么根据这些特点我们该如何解决混音对齐的问题?我们可以分析识别人声的节奏特点,比如我们可以将元音的时间全都找出来,将伴奏的速度找出来,然后再去做宏观偏移,这个宏观偏移是我们整首歌的宏观编译,也可以是按句的宏观偏移。将每一句拉伸,压缩,做偏移,再和伴奏的速度对比,这样就可以比较容易的解决歌手演唱误差导致的时间偏移。例如唱吧的预览界面中展示的一键修音功能。
还有其它有关K歌对齐的问题,比如说丢帧迁移,当本身计算性能有问题的时候,产生丢帧,势必会造成偏移;还有像原唱和伴奏切换时的偏移,原本混音是按伴奏来进行的,但由于原唱和伴奏之前的时间差,人声伴奏在混音时,就会产生一些偏移量。像歌词和伴奏的同步,一般只有在差别比较大的时候才会出现问题,因为人的眼睛相对来说没有那么敏感;然后就是异步合唱,当我唱完歌曲中的一部分后,再去找另外一个人,补充一个唱段,这样就可能会多次产生偏移;当然还有合唱直播,清唱伴奏跟随,DJ无缝切歌,节奏修正等等其它我们可能遇到的一些K歌中的人声伴奏对齐问题。
精品文章推荐
技术干货:
“抖音”式的酷炫短视频开发进阶
Facebook 360度音频编码与渲染
语音编解码技术演进和应用选型
在“小程序”PWA上开发WebRTC
VP9如何给Twitch的电竞直播带来价值?
精致前处理,精准码控 — 极致视觉效果
Pensieve:AI带来的更流畅的高质量观看体验
Netflix:如何通过机器学习提高流媒体质量?