标题:
DSP算法系列教程定点算数运算之从浮点到定点(2)
[打印本页]
作者:
yuyang911220
时间:
2017-6-19 18:43
标题:
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];
}
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0