首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

DSP算法系列教程定点算数运算之从浮点到定点(2)

DSP算法系列教程定点算数运算之从浮点到定点(2)

1.  理论分析法
    有些变量的动态范围通过理论分析是可以确定的。例如:

(1)三角函数。y=sin(x)或y=cos(x),由三角函数知识可知,|y|<=1。

(2)汉明窗。y(n)=0.54一0.46cos[nπn/(N-1)],0<=n<=N-1。因为-1<=cos[2πn/(N-1)]<=1,所以0.08<=y(n)<=1.0。

(3)FIR卷积。y(n)=∑h(k)x(n-k),设∑|h(k)|=1.0,且x(n)是模拟信号12位量化值,即有|x(n)|<=211,则|y(n)|<=211。

(4)理论已经证明,在自相关线性预测编码(LPC)的程序设计中,反射系数ki满足下列不等式:|ki|<1.0,i=1,2,...,p,p为LPC的阶数。

  2.  统计分析法
    对于理论上无法确定范围的变量,一般采用统计分析的方法来确定其动态范围。所谓统计分析,就是用足够多的输入信号样值来确定程序中变量的动态范围,这里输入信号一方面要有一定的数量,另一方面必须尽可能地涉及各种情况。例如,在语音信号分析中,统计分析时就必须来集足够多的语音信号样值,并且在所采集的语音样值中,应尽可能地包含各种情况。如音量的大小,声音的种类(男声、女声等)。只有这样,统计出来的结果才能具有典型性。
    当然,统计分析毕竟不可能涉及所有可能发生的情况,因此,对统计得出的结果在程序设计时可采取一些保护措施,如适当牺牲一些精度,Q值取比统计值稍大些,使用DSP芯片提供的溢出保护功能等。

2.5浮点至定点变换的C程序举例

    本节我们通过一个例子来说明C程序从浮点变换至定点的方法。这是一个对语音信号(0.3~3.4kHz)进行低通滤波的C语言程序,低通滤波的截止频率为800Hz,滤波器采用19点的有限冲击响应FIR滤波。语音信号的采样频率为8kHz,每个语音样值按16位整型数存放在insp.dat文件中。

例1.7语音信号800Hz 19点FIR低通滤波C语言浮点程序。
  • #include  <stdio.h>
  • const int length=180/*语音帧长为180点=22.5ms@8kHz采样*/
  • void filter(int xin[],int xout[],int n,float h[]);/*滤波子程序说明*/
  • /*19点滤波器系数*/
  • static float h[19]=
  • {0.01218354,-0.009012882,-0.02881839,-0.04743239,-0.04584568,
  • -0.008692503,0.06446265,0.1544655,0.2289794,0.257883,
  • 0.2289794,0.1544655,0.06446265,-0.008692503,-0.04584568,
  • -0.04743239,-0.02881839,-0.009012882,O.01218354};
  • static int xl[length+20];
  • /*低通滤波浮点子程序*/
  • void filter(int xin[],int xout[],int n,float h[])
  • {
  • int i,j;
  • float sum;
  • for(i=0;i<length;i++)x1[n+i-1]=xin;
  • for(i=0;i<length;i++)
  • {
  • sum=0.0;
  • for(j=0;j<n;j++)sum+=h[j]*x1[i-j+n-1];
  • xout=(int)sum;
  • for(i=0;i<(n-l);i++)x1[n-i-2]=xin[length-1-i];
  • }
  • /*主程序*/
  • void main()
  • FILE *fp1,*fp2;
  • int frame,indata[length],outdata[length];
  • fp1=fopen(insp.dat,"rb");/* 输入语音文件*/
  • fp2=fopen(Outsp.dat,"wb");/* 滤波后语音文件*/
  • frame=0;
  • while(feof(fp1) ==0)
  • {
  • frame++;
  • printf(“frame=%d\n”,frame);
  • for(i=0;i<length;i++)indata=getw(fp1);  /*取一帧语音数据*/
  • filter(indata,outdata,19,h);/*调用低通滤波子程序*/
  • for(i=0;i<length;i++)putw(outdata,fp2);/*将滤波后的样值写入文件*/
  • }
  • fcloseall();/*关闭文件*/
  • return(0);
  • }

复制代码
例1.8语音信号800Hz l9点FIR低通滤波C语言定点程序。
  • #include <stdio.h>
  • const int length=180;
  • void  filter (int xin[],int xout[],int n,int h[]);
  • static int h[19]={399,-296,-945,-1555,-1503,-285,2112,5061,7503,8450,
  • 7503,5061,2112,-285,-1503,-1555,-945,-296,399};/*Q15*/
  • static int x1[length+20];
  • /*低通滤波定点子程序*/
  • void filter(int xin[],int xout[],int n,int h[])
  • int i,j;
  • long sum;
  • for(i=0;i<length;i++)x1[n+i-111=xin];
  • for(i=0;i<1ength;i++)
  • sum=0;
  • for(j=0;j<n;j++)sum+=(long)h[j]*x1[i-j+n-1];
  • xout=sum>>15;
  • for(i=0;i<(n-1);i++)x1[n-i-2]=xin[length-i-1];
  • }
继承事业,薪火相传
返回列表