一、混响时间的计算与预测

所谓混响就是声音的直达声与反射声很紧凑的重合在一起时人耳所听到的声音,这个效果在语音的后期处理时特别有用。能产生混响最常见的场景就是房间内,尤其是空旷的房间中。

混响有直达声,早期反射和后期反射声组成。其中直达声是声源信号不经过任何障碍物直接到达人耳的那部分、早期反射声由一次或者几次反射的声音信号组成、后期反射声由随后更多次的反射声音信号组成。混响效果的空间感主要由早期反射声决定。

在一个房间中,声音衰减所消耗的时间是房间的吸声系数和声波走过的距离的函数。声波在其传输并衰减的过程中,经过每两个界面之间的平均距离就是众所周知的平均自由程,它可以通过如下公式计算得到:

                     (1.1)

这里:

MFP    平均自由程,单位为米

V     房间的体积,单位为立方米

S     房间的总表面积,单位为平方米

将式(1.1)除以声速,可以得到两次反射的时间间隔为:

                       (1.2)

假如每次反射时,都有a部分能量被墙壁吸收,这时a为墙壁的吸声系数,那么则有(1-a)部分的声能被反射回来,并作用于下一次反射,且每一次都有a部分声能被吸收,因此,经过n次反射后,回来的声能为:

                    (1.3)

由于a为小于1的系数,(1-a)也小于1,因此式(1.3)表示声能按指数规律衰减。为了求出声能衰减到指定比例所需要的时间,就要先求出在指定时间间隔内声波发生反射的次数,而这个可以通过将这个时间间隔除以两次反射的时间间隔得到,基于式(1.2)得到:

                 (1.4)

这里t为混响的总时间(单位为秒),将式(1.4)代入式(1.3)中,得到经过时间t后剩余的声能为:

                  (1.5)

因此,经过一定的时间t后,声能的衰减比例为:

                   (1.6)

对式(1.6)两边取以(1-a)为底的对数得:

                (1.7)

因此,达到一定衰减比例所需要的时间为:

                (1.8)

将以(1-a)为底的对数转换为自然对数(使用高中学过的换底公式)得:

                   (1.9)

式(1.9)给出了声能衰减比例与所需时间的关系,可用于计算所需的时间,即混响时间。我们可以选择无限多种比例进行计算,但最常用的是声能衰减到60dB的声能比,即:10-6。将此值代入式(1.9),得到声能衰减到60dB所需的时间,即混响时间T60为:

      (1.10)

式(1.10)被称为艾润公式,式中负号与自然对数计划结果的负号相抵消,得到一个正的混响时间值。在实际使用中,也可能会遇到计算其它衰减比例的混响时间,其计算方式与式(1.10)相同,不同的是常数部分。

上述公式的推导基于统计学,因此式(1.10)的使用必须具备以后前提条件:

  1. 声波以相同的机率从各个方向到达墙面的各个位置,即声场为扩散声场。这个条件是为了利用房间平均吸声系数的概念。
  2. 平均自由程概念成立。这个也是利用平均吸声系数的条件。它也意味着房间的形状不能太极端,如:很长的隧道就不适合。然而,对于大多数房间,平均自由程的概念是成立的

另外,还有一个较简单的混响时间计算公式,称为赛宾(Sabine)公式,是以其推导者Wallace Clement Sabine的名字命名的。也经常使用。赛宾公式最初是通过考虑房间的平均声能损失、解简单的微分方程推导出来的,但它也可以从艾润公式推导出来,从而更清楚的看到赛宾公式的条件。艾润公式表示如下:

                     (1.11)

上式的困难在于需要计算(1-a)的自然对数。但是自然对数可以用以下无限级数表示:

          (1.12)

因为a < 1,所以上述级数总是收敛的。而且,当a < 0.3时,级数值与a值的误差小于5.7%,这时,式(6.18)可以近似用下式近似:

                  (1.13)

式(1.13)就是赛宾公式,是最早出现的混响时间定量计算公式,也常被使用。

二.混响算法建模与实现

现在我们已经知道了如何计算混响的时间,下面就来看下如何对混响进行建模并实现。要对房间的响应进行建模,我们假设房间内有一个向各个方向辐射的声源,其响应将由声波走过的路径、房间的吸声系数(取决于光滑程度等)来决定、其中房间的吸声系数决定了混响的总体时间,通常混响时间是指在封闭环境中,声能衰减到60dB时所需要的时间。

由于每次反射都会因为墙壁、障碍物等吸收一部分能量,所以声音信号的能量呈指数衰减。因此混响信号可以看成由直达声与许多逐步衰减、不断延迟的回声信号叠加而成,很自然的想到可以利用等比数列求和来进行模拟混响:

        (2.1)

这里x(n)为原始声音信号、y(n)为混响信号、a为衰减系数、D为延迟时间。写成传递函数为:

                (2.2)

由等比数列求和公式,传递函数可以转换为:

                        (2.3)

熟悉信号处理的朋友可能会比较眼熟,这不正是梳状滤波器吗?,一点没错!正是IIR梳状滤波器,其典型的频谱特性为:

如果写成差分方程,可表示为:

                    (2.4)

然而,正如上图中所示,梳状滤波器频谱曲线不平坦,呈现明显的梳状效应,从而对不同的频率成分幅度产生波动,导致有金属声染色效应,听起来不够自然,另外,单纯使用梳状滤波器,其回声密度还是不够多。

那么继续进行思考,什么样的滤波器既有信号的延时效应,频谱又比较平坦呢,很多朋友应该想到了:全通滤波器。是的,接下来使用全通滤波器对混响模型进行改进,它比梳状滤波器多了一个前向反馈支路,一阶全通传递函数可以表示为:

                        (2.5)

其差分方程为:

            (2.6)

  最后,让我们来看Schroeder发明的他的著名的混响产生模型:4个并联的梳状滤波器与2个串连的全通滤波器,如下图所示,在Schroeder混响模型中,梳状滤波器提供了混响效果中延时较长的回声,全通滤波器提供了较短延时的回声,从而增加了反射回声的密度,同时又避免了由于梳状滤波频谱不平坦造成的金属染色效应。

  然而,从实际效果来看,如果完全按照全通滤波器来实现,回声密度还是有点不够理想,改进方法是:不完全使用全通滤波器的实现,人为的增大反馈,使回声的能量增大。这样同样的衰减因子情况下,混响持续的时间就会变长,出来的混响效果会更理想。

  人为的增大反馈,带来的唯一问题是。当个别的语音能量本身比较大时,有时候会带来溢出问题,不过也不用过于担心,通过增大空气湿度的衰减系数就可以很容易调整过来,整体来讲实现效果是比较好的,这部分内容已经在群里进行过好几种方案的讨论,大家都认为实践中人为增加回声反馈效果会更好。

  关于各个滤波器混响时间参数哪些配合起来听感比较自然,其实也是不用去一一再进行研究的,我发现好几个混响的开源实现中,都使用相同的参数配置(忘了最初的资料是哪里了,如果有找到的望不吝啬赐教),据说这样听感比较自然。

  我提取了这些参数,略做了一点修改和整理,写了个测试Demo(TestReverb)。如果有感兴趣的朋友可以到音视频算法讨论QQ群(374737122里下载并交流。欢迎就延时网络法和立体声混响实现进行讨论。

房间声学原理与Schroeder混响算法实现的更多相关文章

  1. Atitti 文本分类  以及 垃圾邮件 判断原理 以及贝叶斯算法的应用解决方案

    Atitti 文本分类  以及 垃圾邮件 判断原理 以及贝叶斯算法的应用解决方案 1.1. 七.什么是贝叶斯过滤器?1 1.2. 八.建立历史资料库2 1.3. 十.联合概率的计算3 1.4. 十一. ...

  2. Gamma原理及快速实现算法(C/C++)(转)

    源:Gamma原理及快速实现算法(C/C++) 原文:http://blog.csdn.net/lxy201700/article/details/24929013 参考 http://www.cam ...

  3. 重新学习Mysql数据库4:Mysql索引实现原理和相关数据结构算法

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  4. Netty源码解析 -- PoolChunk实现原理(jemalloc 3的算法)

    前面文章已经分享了Netty如何实现jemalloc 4算法管理内存. 本文主要分享Netty 4.1.52之前版本中,PoolChunk如何使用jemalloc 3算法管理内存. 感兴趣的同学可以对 ...

  5. 数学建模python matlab 编程(椭圆声学原理画图证明,解析几何)

    证明,在椭圆形的音乐厅内,从一个椭圆的一个焦点发出声音,则另一个焦点听到的声音是最大的. 分析:证明,从椭圆的一个焦点任意发射的直线经过反射后,并经过另一个焦点.            画图,过一个焦 ...

  6. LruCache算法原理及实现

    LruCache算法原理及实现 LruCache算法原理 LRU为Least Recently Used的缩写,意思也就是近期最少使用算法.LruCache将LinkedHashMap的顺序设置为LR ...

  7. 【数据压缩】LZ77算法原理及实现

    1. 引言 LZ77算法是采用字典做数据压缩的算法,由以色列的两位大神Jacob Ziv与Abraham Lempel在1977年发表的论文<A Universal Algorithm for ...

  8. OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

    http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 201 ...

  9. XOR算法的原理和实现

    XOR算法的原理和实现 XOR算法这种方法的原理 当一个数A和另一个数B进行异或运算会生成另一个数C,如果再将C和B进行异或运算则C又会还原为A. 相对于其他的简易加密算法,XOR算法的优点如下. ( ...

随机推荐

  1. android 获取手机型号,本机电话号码,SDK版本以及firmwarw版本号(即系统版本号)

    Android开发平台中,可通过TelephonyManager 获取本机号码. TelephonyManager phoneMgr=(TelephonyManager)this.getSystemS ...

  2. C:进制

     进制.C语言内存分配 1.对于进制 10进制 (0 - 9)16进制 (0——9 A B C D E F)硬件中的高低电平(0 和 1表示)所以计算机用 二进制 机器语言就是由 0 和 1 组成的一 ...

  3. 无责任Windows Azure SDK .NET开发入门篇二[使用Azure AD 进行身份验证]

    二.使用Azure AD进行身份验证 之所以将Azure AD 作为开始,是应为基本上我们所有应用都需要进行安全管理.Azure Active Directory (Azure AD) 通过以下方式简 ...

  4. Json.Net学习笔记

    http://www.cnblogs.com/xiaojinhe2/archive/2011/10/28/2227789.html Newtonsoft.Json(Json.Net)学习笔记 http ...

  5. baseDao 使用spring3+hibernate4方式

    启动异常: java.lang.ClassCastException: org.springframework.orm.hibernate4.SessionHolder cannot be cast  ...

  6. java静态代理与动态代理简单分析

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理 ...

  7. STUN: NAT 类型检测方法

    STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口. STUN 的 ...

  8. Study notes for Clustering and K-means

    1. Clustering Analysis Clustering is the process of grouping a set of (unlabeled) data objects into ...

  9. 导出excel——入门

    简单介绍 Jxl使用总结 样例 java使用jxl操作Excel文件总结

  10. 关于OPenGL和OSG的矩阵 (转)

    关于OPenGL和OSG的矩阵 矩阵真的是一个很神奇的数学工具, 虽然单纯从数学上看, 它并没有什么特别的意义, 但一旦用到空间中的坐标变换,它就“一遇风云便成龙”, 大显神威了.简单的工具实现了复杂 ...