音频淡入淡出效果——解决音频突变的爆音问题

使用软件调节音量时如果音量之间的步进太大,声音突变,就能听到明显的爆音,尤其以单音音频更为明显,类似的问题还在声音起播、暂停、结束、快进快退时经常会出现,这个时候一般需要对音频进行渐入渐出的效果处理。

先来看一个典型的爆音音频示例,播放一个1k hz的正玄波,并调节音量,可以看到波形幅度增大

由于幅度跳变太大,过渡不连续,造成爆音,从频谱图来看这条竖直的亮线处,就是产生爆音的位置

为解决这个问题,就需要引入渐入渐出处理了,声音由大变小时需要做渐出处理,由小变大时需要做渐入处理

所谓渐入渐出处理就是需要一个平滑的过渡,比如从0到1,可以在中间插几个点,平缓的过渡到1,插多少点和每个点的值带来的效果也不一样。这种处理也应用在各种动画过渡场景中,原理相通。

动画效果中经常用到的缓动公式,有兴趣的同学可以深入研究一下其中的数学原理,有几个相关的资料网页:

http://www.timotheegroleau.com/Flash/experiments/easing_function_generator.htm

这个网页十分强大,可以手动设计缓动效果并生成对应的函数接口

http://blog.moagrius.com/actionscript/jsas-understanding-easing/

这个网页详细解释了函数公式的意义:

These functions are usually written with 4 arguments [2]:


function noEasing (t, b, c, d) {
	return c * t / d + b;
}
@t is the current time (or position) of the tween. This can be seconds or frames, steps, seconds, ms, whatever – as long as the unit is the same as is used for the total time [3].
@b is the beginning value of the property.
@c is the change between the beginning and destination value of the property.
@d is the total time of the tween.

这里的解释是针对动画效果而言,翻译成音频来说,我们的音量假设从0增大到1.0

b就代表起始音量0,c表示目标音量到起始音量的差即1.0

d意味着需要对多少样本做处理,一般我们会以时间来计算,比如我要200ms内的音频数据缓动处理,那么这么样本总值就是:

d = 200*sr(采样率)/1000  ,因为左右声道是同时处理,我们以frame为单位,48000采样率,d的大小为9600

t就是处理的frame计数了,从0到9600增加,返回值就是当前的frame需要的当前音量,参考代码如下:


vol_delta = target_volume - current_volume;
for (j = 0; j < nframes; j++) {
          if (ease_frames == 0) {
                     current_volume = target_volume;
          } else if (ease_frames_elapsed < ease_frames) {

                        current_volume= floatEaseNext((float)ease_frames_elapsed,
                                                    start_volume, vol_delta, (float)(ease_frames - 1));
                        ease_frames_elapsed++;
                    }
			
                    for (i = 0 ; i < ch; i++) {
                        data[j * ch + i] = data[j * ch + i] * current_volume;
                    }
       }

公式有很多种,每种公式处理的过渡效果不一,这是两种ease in和ease out的处理公式

EaseInCubic:
floatEaseFunc( float t, float b, float c, float d) {
        t /= d;
        return c * t * t * t + b;
}
EaseOutCubic:
       floatEaseFunc( float t, float b, float c, float d) {
         t = t / d - 1;
        return c * (t * t * t + 1) + b;
}

来看一下实际对音频突变的处理效果,这是系统在播放1Khz时不断调整音量时dump的pcm数据

我们从频谱图上来看

整段音频非常干净,没有任何杂音爆破音,处理的相当完美。

据了解缓动公式由大神robert penner提出,再次感谢膜拜大神!

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值