上篇文章(基于MCRA-OMLSA的语音降噪(二):实现)讲了基于MCRA-OMLSA的语音降噪的软件实现。本篇继续讲,主要讲C语言下怎么对数学库里的求平方根(sqrt())、求自然指数(exp())、求自然对数(log())的函数做替换。

1,求平方根

求平方根最常用的方法是牛顿迭代法。下图是y = f(x)的曲线,当f(x) =0时的值(α)就是该方程的根。

可以通过多次迭代逼近的方法求得这个根,原理如下:

任取一个x0,这个值对应的y值为f(x0)。在x0处画y = f(x)的切线,与x轴交点为x1。根据斜率的定义,在x0处的斜率如下:

又斜率是函数的一次导数f’(x0),所以

可求得

基于x1再画一条切线,运用上面的求法得到与x轴交点为x2,一直迭代下去可得x3,…….,xn,xn+1等,从而求得xn+1与xn的关系如下式:

这些值会向方程的根α无限逼近。当| xn+1 - xn| < ε (ε是事先设定的一个精度)时就停止迭代,这时xn+1就是方程f(x) = 0的根。

具体到求平方根,x2 = v (v是一个大于等于0的实数值),x2 – v = 0,令f(x) = x2 – v ,得到f’(x) = 2x,把f(x)和f’(x)带入上式得到

处理后得到

上式就是求平方根的迭代数学表达式。设定好精度后就可求出平方根,与C数学库的sqrt()结果比较,值是非常接近的。

2,求自然指数

求自然指数是基于论文《指数函数ex的快速计算方法》。用这个方法前得搞清楚浮点数的二进制存储表示方法,浮点数包括单精度浮点数(float)和双精度浮点数(double)。先看float的二进制存储表示,float的搞明白了,double的类似,也好懂。

float占4个字节,32比特,存储格式如下图:

其中第0-22位共23位表示尾码M,第23-31位共8位表示阶码E,第31位共1位表示符号位S。符号位好理解,0表示正数,1表示负数。以0.625为例,是正数,所以符号位是0。至于阶码和尾码,方便理解,依旧以0.625为例。0.625 = 1.25 *  2-1 = (1 + 0.25) *  2-1 = (1 + x) * 2y,其中x表示小数部分,y表示指数。

阶码E = y + 127 的二进制表示。这里y = -1,所以E = -1 + 127 = 126,表示成二进制就是1111110,用8位二进制表示就是01111110。

尾码M = x * 223的二进制表示。这里x = 0.25,所以0.25 * 223= 2097152,用23位的二进制表示,M = 01000000000000000000000。

最终0.625的二进制存储表示如下图:

double占8个字节,64比特,存储格式如下图:

它的二进制表示跟float类似,不同的是阶码E = y + 1023。依旧以0.625为例,

阶码E = -1 + 1023 = 1022,表示成二进制就是1111111110,用11位二进制表示就是01111111110。

尾码M = x * 252的二进制表示。这里x = 0.25,所以0.25 * 252= 1125899906842624,用52位的二进制表示,M = 0100000000000000000000000000000000000000000000000000。符号位还是0。最终0.625的二进制存储表示如下图:

浮点数的存储机制搞明白了,现在看怎么求自然指数。求自然指数的传统方法是用指数函数的幂级数展开式,如下式:

该论文用了一种计算速度更快的方法。下面具体看怎么做的。为简单起见,令x > 0,当x < 0时,只要用1除就可以了。

令 y = ex,所以 。log2e是个定值1.4426950408889634,这里令为a,即a = log2e = 1.4426950408889634。从而log2y = ax,即 y = 2ax。令n是ax的整数部分,即 n = [ax],从而ax的小数部分为ax – n,令其为D,即D = ax – n。所以 ax = n + D,y = 2ax = 2n+D = 2D2n 。因为 0 < D < 1,所以1 < 2D < 2,从而可以写成1 + α(0 < α < 1)的形式,所以 y = (1 + α)2n。对标C数学库里exp()用的是double型,这里也用double型。根据上文double型的二进制存储形式,可知n+1023就是阶码,α*252就是尾码。n很好求,ax取整就可以了。下面看α怎么求。α = 2D – 1,2D求出,α就有了。

令p = 2D,从而 。令x00 = Dln2,有p = ex00。因为 0 < D < 1,又ln2 = 0.69314718056,所以 0 < x00 < 0.69314718056。此时若直接用ex00的幂级数展开式求p,计算时间还很长,若适当选取x0和Δx,使得Δx << 1,且 x00 = x0 + Δx,则有 p = ex0 + Δx = ex0eΔx。可分别求ex0和eΔx,然后再相乘就得到p。论文中用查表法求ex0,用幂级数展开法求eΔx。先看怎么求ex0。将x00转换为16进制数表示,改写成x00 = 0.q1q2q3q4q5n = 0.q1q2q3 + 0.000q4q5n =  x0 + Δx,其中x0 = 0.q1q2q3 = q1 * 16-1 + q2 * 16-2 + q3 * 16-3,Δx = 0.000q4q5n = q4 * 16-4 + q5 * 16-5 + ...。所以ex0 = eq1 * 16-1 + q2 * 16-2 + q3 * 16-3 = eq1 * 16-1eq2 * 16-2eq3 * 16-3。因为x0 < x00 < 0.69314718056 < 0.75 = 12/16,所以q1的取值范围是[0, 11],q2的取值范围是[0, 15],q3的取值范围是[0, 15]。根据qx的有限个不同取值将eq1 * 16-1 、eq2 * 16-2 和eq3 * 16-3 分别预先算出做成表,计算时通过查表得到三个相应的值,再将这三个值相乘就得到ex0的值了。再来看怎么求eΔx。0 < Δx  = 0.000q4q5n < 16-3 = 1/4096 << 1,用幂级数展开式求eΔx只要取前面4项即可保证精度了,所以用幂级数展开式求eΔx

下面给出软件实现时的步骤:

1)     定义结构体如下,其中s放符号位,e放阶码,m放尾码,dat是自然指数运算的返回值。

typedef union {

double dat;

struct{

unsigned long m:52;

unsigned e:11;

unsigned s:1;

}jw;

}FREXP;

2)     求符号位和阶码。因为自然指数均大于0,所以符号位均为0。对ax取整加1023就可得阶码。

3)     求尾码。通过查表法求ex0,通过幂级数展开式求eΔx,p = ex0eΔx即可求得,α = p – 1也可求得。尾码 =α*252就得到了。

4)     返回dat值就是自然指数的结果了。

3,求自然对数

自然对数是自然指数的逆运算,y = ex,根据y求x。给定一个y,通过上面定义的结构体FREXP可以得到它的阶码E和尾码M(Mi表示每一位上的值),表示如下式:

又 y = ex,所以

上式两边取自然对数,得到:

即:

其中

b好求,主要看a怎么求。a是ln(1 + x)的形式,泰勒展开式如下:

所以可以用泰勒展开式求b。a和b都求出来了,一个数y的自然对数x = a + b就求出来了。

下面给出软件实现时的步骤(与自然指数共用结构体):

1)     得到阶码E和尾码Mi

2)     根据阶码E求得b

3)     根据尾码Mi利用泰勒展开式得到a

4)     将a和b相加就得到自然对数

基于MCRA-OMLSA的语音降噪(三):实现(续)的更多相关文章

  1. webRTC中语音降噪模块ANS细节详解(一)

    ANS(adaptive noise suppression) 是webRTC中音频相关的核心模块之一,为众多公司所使用.从2015年开始,我在几个产品中使用了webRTC的3A(AEC/ANS/AG ...

  2. 基于MCRA-OMLSA的语音降噪(一):原理

    前面的几篇文章讲了webRTC中的语音降噪.最近又用到了基于MCRA-OMLSA的语音降噪,就学习了原理并且软件实现了它.MCRA主要用于噪声估计,OMLSA是基于估计出来的噪声去做降噪.类比于web ...

  3. 基于MCRA-OMLSA的语音降噪(二):实现

    上篇文章(基于MCRA-OMLSA的语音降噪(一):原理)讲了基于MCRA-OMLSA降噪的原理,本篇讲怎么做软件实现.软件实现有多种方式.单纯看降噪效果可用python,因为python有丰富的库可 ...

  4. webRTC中语音降噪模块ANS细节详解(三)

    上篇(webRTC中语音降噪模块ANS细节详解(二))讲了ANS的处理流程和语音在时域和频域的相互转换.本篇开始讲语音降噪的核心部分,首先讲噪声的初始估计以及基于估计出来的噪声算先验信噪比和后验信噪比 ...

  5. webRTC中语音降噪模块ANS细节详解(二)

    上篇(webRTC中语音降噪模块ANS细节详解(一))讲了维纳滤波的基本原理.本篇先给出webRTC中ANS的基本处理过程,然后讲其中两步(即时域转频域和频域转时域)中的一些处理细节. ANS的基本处 ...

  6. webRTC中语音降噪模块ANS细节详解(四)

    上篇(webRTC中语音降噪模块ANS细节详解(三))讲了噪声的初始估计方法以及怎么算先验SNR和后验SNR. 本篇开始讲基于带噪语音和特征的语音和噪声的概率计算方法和噪声估计更新以及基于维纳滤波的降 ...

  7. 基于图的异常检测(三):GraphRAD

    基于图的异常检测(三):GraphRAD 风浪 一个快乐的数据玩家/风控/图挖掘 24 人赞同了该文章 论文:<GraphRAD: A Graph-based Risky Account Det ...

  8. 语音降噪论文“A Hybrid Approach for Speech Enhancement Using MoG Model and Neural Network Phoneme Classifier”的研读

    最近认真的研读了这篇关于降噪的论文.它是一种利用混合模型降噪的方法,即既利用了生成模型(MoG高斯模型),也利用了判别模型(神经网络NN模型).本文根据自己的理解对原理做了梳理. 论文是基于" ...

  9. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

随机推荐

  1. 08-认证(Authorization)

    这又是一个非常实用的功能,对我们做接口测试来说,经常要处理登录认证的情况 .如果不用这个Authorization其实也能解决认证的问题,无非就是把要认证的数据按照要求在指定位置传入参数即可.比如我们 ...

  2. Spring(2):依赖注入DI

    依赖注入DI 当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例.但在Spring里,创建被 ...

  3. FastDFS的理解和分析

    FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为载体的在线服务,如相 ...

  4. 部署应用程序到Tomcat的webapps目录

    一.方法如下 1.通过MyEclipse上方工具栏Manage Deployments,依次选择项目和服务器: 2.通过右击项目Export,生成war包到webapps中: 3.复制项目WebRoo ...

  5. Docker从入门到精通(五)——Dockerfile

    Dockerfile 简单来说就是一个包含用于组合镜像的命令的文本文档,Docker 通过读取 Dockerfile 中的指令就可以按步骤生成镜像,那么在制作镜像之前,我们先了解一下镜像的原理. 1. ...

  6. mobile app 与server通信的四种方式

    Have you ever wondered how the information gets into the application installed in your mobile device ...

  7. 统计函数(Excel函数集团)

    此处文章均为本妖原创,供下载.学习.探讨! 文章下载源是Office365国内版1Driver,如有链接问题请联系我. 请勿用于商业! 谢谢 下载地址:https://officecommunity- ...

  8. logging模块学习

    logging模块: https://docs.python.org/3/howto/logging.html#logging-basic-tutorial 本记录教程 日志记录是一种跟踪某些软件运行 ...

  9. TCP 长连接保活机制&HTTP长连接设置

    TCP KeepAlive Wireshark抓包分析机制 -------------------------------- 如上图所示,TCP保活报文总是成对出现,包括TCP保活探测报文和TCP保活 ...

  10. 将本地的react项目代码打包到服务器

    打包过程 连接服务器 ssh root@xx.xx.xx.xx(服务器IP) 定位到当前项目目录 cd /path/projectName 更新代码到服务器 git pull 执行打包命令(这里我创建 ...