上篇文章(基于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. virtualBox 系统移植

    把virtualbox已经存在的系统移植到其他机器. 1.把系统如下文件考到一个安装了virtualbox的机器. 2.点击控制-->注册 然后浏览到复制的文件路径. 3.修改uuid 不管是l ...

  2. 手写Starter

    一. Starter工程的命名 Spring 官方定义的Starter通常命名遵循的格式为spring-boot-starter-{name},例如 spring-boot-starter-web.S ...

  3. FastDFS的理解和分析

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

  4. 搭建mybatis开发环境

    1.创建工程 <groupId>com.hope</groupId>     <artifactId>day01_eesy_01mybatis</artifa ...

  5. 莫烦python教程学习笔记——数据预处理之normalization

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...

  6. numpy基础教程--将二维数组转换为一维数组

    1.导入相应的包,本系列教程所有的np指的都是numpy这个包 1 # coding = utf-8 2 import numpy as np 3 import random 2.将二维数组转换为一维 ...

  7. shell脚本 批量查看mysql表条目数

    一.简介 源码地址 日期:2018/4/12 介绍:查看mysql的信息,用于比对和查询条目数 效果图: 二.使用 适用:centos6+ 语言:中文 注意:适用于5.7版本,其它版本要更改变量han ...

  8. pipeline脚本管理

    目录 一.代码仓库 二.远程拉取 一.代码仓库 1.使用gitlab做pipeline脚本的存储,新建一个仓库 2.新建文件,把代码放进去 脚本名可以按照规律填写,环境_应用名_类型,例如:test_ ...

  9. Linux实体服务器添加网卡

    目录 一.简介 二.配置 三.添加网卡 四.总结 一.简介 服务器如果搭配了网口,在插入网线或者光纤后会亮灯.如果发现不亮,可以关闭机器查看亮不亮,因为有的时候系统会把网口禁用,进入到系统反而不亮了, ...

  10. A New Discrete Particle Swarm Optimization Algorithm

    题目:一种新的离散粒子群优化算法 中文摘要 粒子群优化算法在许多优化问题上表现得非常好.粒子群优化算法的缺点之一是假设算法中的变量为连续变量.本文提出一个新的粒子群优化算法,能够优化离散变量.这个新算 ...