OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3917|回复: 7

请教懂音乐频谱的,烦请解释一下面的各条语句的含义。

[复制链接]

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
发表于 2017-10-14 09:31:54 | 显示全部楼层 |阅读模式
1金钱
请教懂音乐频谱的,解释一下面的各条语句的含义。主要是这些语句中除256,乘32768,乘65536等是什么作用?最好能给每句加个注释,本人智商低下,看不懂,只能求助了。谢谢!!!

void powerMag()
{         int32_t lX,lY;
                uint32_t i;
                for (i=0;i<256;i++)
                {
                        lX=(lBUFOUT<<16)>>16; /* sine_cosine --> cos */
                        lY=(lBUFOUT>>16);   /* sine_cosine --> sin */     
                        {
                                float X=256*((float)lX)/32768;
                                float Y=256*((float)lY)/32768;
                                float Mag = sqrt(X*X+ Y*Y)/256;  // 先平方和,再开方
                                lBUFMAG =(long)(Mag*65536);
                        }     
                }
}

最佳答案

查看完整内容[请看2#楼]

这是在网上找到的最详细的解释,贴上来共享: 之所以语句这么写是基于芯片的计算习惯,DSP最擅长的就是浮点数的乘机运算。语句分析如下: 首先定义的的一个16位的有符号的数据IX 和IY 这两个只是中间变量,然后定义的i,是32位的无符号型。 语句的目的的确是你理解的Mag = sqrt(X*X + Y*Y)/NPT。但直接这么写不符合DSP的计算习惯,也就是不符合浮点运算的习惯。因此语句在for函数i写道 lX = (lBUFOUT > 16 / ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2017-10-14 09:31:55 | 显示全部楼层
本帖最后由 rjx007 于 2017-10-17 13:44 编辑

      这是在网上找到的最详细的解释,贴上来共享:
     之所以语句这么写是基于芯片的计算习惯,DSP最擅长的就是浮点数的乘机运算。语句分析如下:
首先定义的的一个16位的有符号的数据IX 和IY 这两个只是中间变量,然后定义的i,是32位的无符号型。
语句的目的的确是你理解的Mag = sqrt(X*X + Y*Y)/NPT。但直接这么写不符合DSP的计算习惯,也就是不符合浮点运算的习惯。因此语句在for函数i写道
    lX  = (lBUFOUT << 16) >> 16   //就是取32位的i的低16位数据,
    lY  = (lBUFOUT >> 16);        //是取高16位数据。下面的两句
    float X    = NPT * ((float)lX) /32768;   
    float Y    = NPT * ((float)lY) /32768
    目的就是把数据浮点化,至于为什么是除以32768 。可以这么说,浮点化 就好像10进制里面的科学计数法。32768=2的15次方。除以32768也就是去除了浮点数后面的那个基数,只剩下前面的。比如1991 改写成1.991*10的三次幂,再除以10的三次方,只剩下1.991,便于余下的运算。
    之后的语句就不用解释了吧?至于最后一句要乘以65536,是因为我们定义的数据和我们需要求得的数据都是无符号32位的,
   之前已经把32位的数据拆开又分别浮点化了,又开了个根号,所以再把它变回来 只需要乘以2的16次,也就是65536.
    打个比方吧。比如说问你什么时候生日,你说是19911030,然而DSP是不习惯这么干的,他需要把它拆开为1991和1030。再写成1.991x10的3次方和1.030x10的3次方。然后才能进行其他的运算。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-10-15 01:06:56 | 显示全部楼层
这里是算平方根,取模
回复

使用道具 举报

19

主题

49

帖子

0

精华

高级会员

Rank: 4

积分
728
金钱
728
注册时间
2015-8-20
在线时间
58 小时
发表于 2017-10-15 05:06:51 | 显示全部楼层
这只是一个单纯的数学运算。
把IBUFOUT高16位和低16位的平方和进行开方  (最终的结果还乘了一个系数2)。
单纯从代码上看就好像是求直角三角形斜边长(的2倍)
或者
复数的模(的2倍)

具体的要看他实际物理意义。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2017-10-15 15:04:15 | 显示全部楼层
说明一下,以上函数是求复数的模。但每条语句是干什么,不懂。如:
   lX=(lBUFOUT<<16)>>16; /* sine_cosine --> cos */     先左移16位,又右移16位,不是等于没有移位了?
回复

使用道具 举报

0

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
297
金钱
297
注册时间
2017-10-12
在线时间
83 小时
发表于 2017-10-16 01:19:30 | 显示全部楼层
rjx007 发表于 2017-10-15 15:04
说明一下,以上函数是求复数的模。但每条语句是干什么,不懂。如:
   lX=(lBUFOUT16; /* sine_cosine --> ...

这个算式的目的是典型的16位整型带符号扩展到32位整型,即把D15位扩展到D16~D31
回复

使用道具 举报

头像被屏蔽

12

主题

167

帖子

0

精华

禁止访问

积分
517
金钱
517
注册时间
2017-5-30
在线时间
110 小时
发表于 2017-10-16 10:38:48 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2018-4-15
在线时间
6 小时
发表于 2018-4-15 15:53:34 | 显示全部楼层
我也来学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 19:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表