OpenEdv-开源电子网

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

移植codec2的fft出现与电脑运行结果有区别

[复制链接]

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2019-10-24
在线时间
11 小时
发表于 2019-10-27 08:20:38 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 科技骏马 于 2019-10-27 08:27 编辑

我把codec2移植到STM32F409+CubeMX+freeRTOS+fatfs,开发板不是原子的,是杂牌的,从SD卡上读取raw语音,用450bps编码后再写到SD卡,在电脑上解码后听不清,用电脑编码的同一段声音再用电脑解码还能听清。我调试中发现最初与电脑运行过程有分歧的是make_analysis_window函数中codec2_fft的结果W数组,可能是arm_cfft_f32与kiss_fft有差异造成的,但是执行analyse_one_frame中dft_speech的codec2_fft_inplace里面也有arm_cfft_f32,结果都与电脑执行结果相同。我贴一下核心代码,在sine.c中
  1. void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[])
  2. {
  3.   float m;
  4.   COMP  wshift[FFT_ENC];
  5.   COMP  temp;
  6.   int   i,j;
  7.   int   m_pitch = c2const->m_pitch;
  8.   int   nw      = c2const->nw;
  9.   //这里删除了一些注释

  10.   m = 0.0;
  11.   for(i=0; i<m_pitch/2-nw/2; i++)
  12.   w[i] = 0.0;
  13.   for(i=m_pitch/2-nw/2,j=0; i<m_pitch/2+nw/2; i++,j++) {
  14.   w[i] = 0.5 - 0.5*cosf(TWO_PI*j/(nw-1));
  15.   m += w[i]*w[i];
  16.   }
  17.   for(i=m_pitch/2+nw/2; i<m_pitch; i++)
  18.   w[i] = 0.0;

  19.   /* Normalise - makes freq domain amplitude estimation straight
  20.      forward */

  21.   m = 1.0/sqrtf(m*FFT_ENC);
  22.   for(i=0; i<m_pitch; i++)
  23.   w[i] *= m;
  24.   //这里删除了一些注释
  25.   for(i=0; i<FFT_ENC; i++) {
  26.   wshift[i].real = 0.0;
  27.   wshift[i].imag = 0.0;
  28.   }
  29.   for(i=0; i<nw/2; i++)
  30.   wshift[i].real = w[i+m_pitch/2];
  31.   for(i=FFT_ENC-nw/2,j=m_pitch/2-nw/2; i<FFT_ENC; i++,j++)
  32.   wshift[i].real = w[j];
  33.   codec2_fft(fft_fwd_cfg, wshift, W);//这里开始进入codec2_fft.h的内联函数,这里出错了
  34.   //这里删除了一些注释
  35.   for(i=0; i<FFT_ENC/2; i++) {
  36.   temp.real = W[i].real;
  37.   temp.imag = W[i].imag;
  38.   W[i].real = W[i+FFT_ENC/2].real;
  39.   W[i].imag = W[i+FFT_ENC/2].imag;
  40.   W[i+FFT_ENC/2].real = temp.real;
  41.   W[i+FFT_ENC/2].imag = temp.imag;
  42. }
  43. }
复制代码
在codec2_fft.h中,USE_KISS_FFT未定义,执行宏定义else中的语句
  1. static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out)
  2. {
  3. #ifdef USE_KISS_FFT
  4.   kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out);
  5. #else
  6.   memcpy(out,in,cfg->instance->fftLen*2*sizeof(float));
  7.   arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse, 1);
  8.   //这里删除了一些注释
  9.   if (cfg->inverse)
  10.   {
  11.     arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2);
  12.   }
  13. #endif
  14. }
复制代码

需要完整代码的,请查看附件

源码.zip

6.46 MB, 下载次数: 25

项目源码

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2019-7-30
在线时间
3 小时
发表于 2020-6-6 21:43:56 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 11:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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