DSP中浮点转定点运算--举例及编程中的心得

5.举例及编程中的心得

5.1举例

  “第3章  DSP芯片的定点运算.doc”这篇文章中给了一个很简单有能说明问题的例子,不想动大脑了,直接引用过来如下。

  这是一个对语音信号(0.3kHz~3.4kHz)进行低通滤波的C语言程序,低通滤波的截止频率为800Hz,滤波器采用19点的有限冲击响应FIR滤波。语音信号的采样频率为8kHz,每个语音样值按16位整型数存放在insp.dat文件中。

例3.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,0.01218354};
static  int x1[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[i];
    for (i=0;i<length;i++)
    {
        sum=0.0;
        for(j=0;j<n;j++) sum+=h[j]*x1[i-j+n-1];
        xout[i]=(int)sum;
    }
    for(i=0;i<(n-1);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[i]=getw(fp1);        /*取一帧语音数据*/
        filter(indata,outdata,19,h);            /*调用低通滤波子程序*/
        for(i=0;i<length;i++)  putw(outdata[i],fp2);     /*将滤波后的样值写入文件*/
    }
    fcloseall( );                   /*关闭文件*/
    return(0);
}

例3.8  语音信号800Hz 19点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-1]=xin[i];
    for (i=0;i<length;i++)
    {
        sum=0;
        for(j=0;j<n;j++)  sum+=(long)h[j]*x1[i-j+n-1];
        xout[i]=sum>>15;
    }
    for(i=0;i<(n-1);i++) x1[n-i-2]=xin[length-i-1];
}

主程序与浮点的完全一样。

5.2编程中的心得

  通过上边的例子,相信大家都大致明白了转换的过程。一个函数模块如此,一个大的软件项目的转换也无非如此。所不同的是,对于一个项目,很少有一个个单独的模块,一般都是几个或数个模块都有联系,千一发而动全身,所以,再进行转换之前,最好理清各个软件模块之间的关系。

  协调,协调,再协调。

  写到这里, 与afreez一起学习DSP中浮点转定点运算这个问题的讨论终于可以收笔了。拖拖拉拉,拉了有3个月之久,现在终于可以了却自己的愧疚了。从第三部分开始,写的有写着急,因为没有足够的时间来写,还想把剩下的写完,只能这么解决了。我想,文章只是给出学者一个思路,如果自己以后遇到了这样的问题,还需要自己去探索的,没有一劳永逸的文章,毕竟问题都各个不同吗。

  文章中难免有不妥之处,欢迎大家批评指正!

以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略

    4.定点数模拟浮点数运算及常见的策略 相信大家到现在已经大致明白了浮点数转换成定点数运算的概貌.其实,原理讲起来很简单,真正应用到实际的项目中,可能会遇到各种各样的问题.具我的经验,常见的策略有如下几条: 1)除法转换为乘法或移位运算 我们知道,不管硬件平台如果变换,除法运算所需要的时钟周期都远远多于乘法运算和加减移位运算,尤其是在嵌入式应用中,"效率"显得尤为重要.以笔者的经验,其实,项目中的很大一部分除法运算是可以转换成乘法和移位运算,效率还是有很大提升空间的. 2)查表计算 有些

  • 浮点数在计算机中存储方式是怎样的

    C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53. 无论是单精度还是双精度在存储中都分为三个部分: 1.符号位(Sign

  • DSP中浮点转定点运算--浮点与定点概述

    一:浮点与定点概述 1.1相关定义说明 定点数:通俗的说,小数点固定的数.以人民币为例,我们日常经常说到的如123.45¥,789.34¥等等,默认的情况下,小数点后面有两位小数,即角,分.如果小数点在最高有效位的前面,则这样的数称为纯小数的定点数,如0.12345,0.78934等.如果小数点在最低有效位的后面,则这样的数称为纯整数的定点数,如12345,78934等. 浮点数:一般说来,小数点不固定的数.比较容易的理解方式是,考虑以下我们日常见到的科学记数法,拿我们上面的数字举例,如123.

  • DSP中浮点转定点运算--浮点数的存储格式

    二:浮点数的存储格式 2.1 IEEE floating point standard 上面我们说了,浮点数的小数点是不固定的,如果每个人都按照自己的爱好存储在电脑里,那不就乱套了吗?那么怎么在计算机中存储这种类型的数字呢?象这类古老的问题前人早都为我们做好了相应的规范,无规矩不成方圆吗.我们平时所说的浮点数的存储规范,就是由IEEE指定的,具体的规范文件是:IEEE Standard 754 for Binary Floating-Point Arithmetic.大家可以很容易的从网络上下载

  • 深入C/C++浮点数在内存中的存储方式详解

    任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中,存放方式为  10000100(低地址单元) 00000100(高地址单元),因为Intel CPU的架构是小端模式.但是对于浮点数在内存是如何存储的?目前所有的C/C++编译器都是采用IEEE所制定的标准浮点格式,即二进制科学表示法.在二进制科学表示法中,S=M*2^N 主要由三部分构成:符号位+阶码(N)+尾数(M).对于flo

  • DSP中浮点转定点运算--定点数的加减乘除运算

    3.定点数的加减乘除运算 简单的说,各种运算的原则就是先把待运算的数据放大一定的倍数,在运算的过程中使用的放大的数据,在最终需要输出结果的时候再调整回去. 举个例来说,有如下运算: 复制代码 代码如下: - // coefs1 = 0.023423; coefs2=0.2131 float coefs1,coefs2; int result; - result = 34* coefs1+72* coefs2; - 代码的意思是,该模块需要输出一个整型的结果,但计算的过程中有浮点的运算.如果在定点

  • DSP中浮点转定点运算--举例及编程中的心得

    5.举例及编程中的心得 5.1举例 "第3章  DSP芯片的定点运算.doc"这篇文章中给了一个很简单有能说明问题的例子,不想动大脑了,直接引用过来如下. 这是一个对语音信号(0.3kHz~3.4kHz)进行低通滤波的C语言程序,低通滤波的截止频率为800Hz,滤波器采用19点的有限冲击响应FIR滤波.语音信号的采样频率为8kHz,每个语音样值按16位整型数存放在insp.dat文件中. 例3.7  语音信号800Hz 19点FIR低通滤波C语言浮点程序 复制代码 代码如下: #inc

  • 举例讲解设计模式中的访问者模式在Java编程中的运用

    访问者(Visitor)模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作.访问者模式的结构图如下: 通过上图可以看到他有如下角色: 抽象访问者(Visitor)角色:定义接口,声明一个或多个访问操作. 具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作. 抽象元素(Visitable)角色:声明一个接受操作,接受一个访问者对象作为一个参数. 具体元素结点(Concret

  • 浅析设计模式中的代理模式在C++编程中的运用

    由遇到的问题引出代理模式 至少在以下集中情况下可以用代理模式解决问题: 创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF 称之为虚代理(Virtual Proxy): 为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成,GoF 称之为远程代理(Remote Proxy): 对对象进行控制访问的时候,比如在 Jive 论坛中不同权限的用户(如管理员.普通用户等)将获得

  • 举例解析Java的设计模式编程中里氏替换原则的意义

    里氏替换原则,OCP作为OO的高层原则,主张使用"抽象(Abstraction)"和"多态(Polymorphism)"将设计中的静态结构改为动态结构,维持设计的封闭性."抽象"是语言提供的功能."多态"由继承语义实现. 里氏替换原则包含以下4层含义: 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法. 子类中可以增加自己特有的方法. 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更

  • 举例讲解C#编程中委托的实例化使用

    合并委托 本示例演示如何创建多播委托. 委托对象的一个有用属性是:可以使用 + 运算符将多个对象分配给一个委托实例.多播委托包含已分配委托的列表.在调用多播委托时,它会按顺序调用列表中的委托.只能合并相同类型的委托. - 运算符可用于从多播委托中移除组件委托. using System; // Define a custom delegate that has a string parameter and returns void. delegate void CustomDel(string

  • 举例讲解Java编程中this关键字与super关键字的用法

    this 总要有个事物来代表类的当前对象,就像C++中的this指针一样,Java中的this关键字就是代表当前对象的引用. 它有三个主要的作用: 1.在构造方法中调用其他构造方法.       比如有一个Student类,有三个构造函数,某一个构造函数中调用另外构造函数,就要用到this(),而直接使用Student()是不可以的. 2.返回当前对象的引用. 3.区分成员变量名和参数名. 看下面的例子: public class Student { private String name; p

随机推荐