首页 > 解决方案 > 将窗口应用于音频样本会拧紧输出

问题描述

使用 arm_mult_f32 将两个数组相乘会产生意外(垃圾)结果。

我一直在阅读有关dsp的信息。在 FFT 之前,我正在创建 Hann 系数以应用于采样的 PCM 数据。

hanning 函数来自我发现的 hann.m matlab 示例,唯一的区别是 stm32f4 只有一个单精度 FPU,所以我将 uint32_t 用于数据字段而不是双精度。

首先,定义。

FFT_LEN = 256;                   

float32_t FFTBuf[FFT_LEN * 2];   // data set twice the fft length as output 

                                 //symetrically repeated
float32_t FFTMagBuf[FFT_LEN];    //

float32_t * hann_window;
float32_t * hann_buff;
float32_t * hanning(uint32_t, uint8_t)

调用 hanning 函数来填充窗口。

hann_window = hanning(FFT_LEN * 2, 2);    // creates a dynamic array and 
                                          //populates it with coeffs.


hann_buff = (float32_t *)calloc(FFT_LEN * 2, (sizeof(float32_t)));
memset(hann_buff, 0, FFT_LEN * 2 * sizeof(float32_t));   //intermediate 
                                                         //buffer



then when all pcm samples are read

arm_mult_f32(FFTBuf, &hann_window[0], &hann_buff[0], (FFT_LEN * 2)); // 

arm_cfft_f32(&arm_cfft_sR_f32_len256, &hann_buff[0], 0, 1);

arm_cmplx_mag_f32(&hann_buff[0], FFTMagBuf, FFT_LEN);

hann函数如下

float32_t *hanning(uint32_t N, uint8_t itype)
  {
    uint32_t half, i, idx, n;
    float32_t *w;

    w = (float32_t *)calloc(N, sizeof(float32_t));
    memset(w, 0, N * sizeof(float32_t));

    if (itype == 1) //periodic function
      n = N - 1;
    else
      n = N;

    if (n % 2 == 0)
    {
  half = n / 2;
  for (i = 0; i < half; i++) //CALC_HANNING   Calculates Hanning window samples.
    w[i] = 0.5 * (1 - cos(2 * PI * (i + 1) / (n + 1)));

  idx = half - 1;
  for (i = half; i < n; i++)
  {
    w[i] = w[idx];
    idx--;
  }
}
else
{
  half = (n + 1) / 2;
  for (i = 0; i < half; i++) //CALC_HANNING   Calculates Hanning window samples.
    w[i] = 0.5 * (1 - cos(2 * PI * (i + 1) / (n + 1)));

  idx = half - 2;
  for (i = half; i < n; i++)
  {
    w[i] = w[idx];
    idx--;
  }
}

if (itype == 1) //periodic function
{
  for (i = N - 1; i >= 1; i--)
    w[i] = w[i - 1];
  w[0] = 0.0;
}
return (w);
  }

没有窗口函数我得到了很好的值,我用 4khz 正弦波测试了代码,它给出了正确的结果(没有 hann 窗口的东西)

新输出的样本看起来不太好。

{1.10114283e-019, 0 <repeats 48 times>, 35050560, inf, 0.0352631919, 
1.08468142e-019, 2.84188939e-009, inf, 143872, 142068.25, 3.31743232e+010, 
8800024, 3.29058877e+010, 0, 1.53397155e-019, 4.58692708e-013, 61631.5938, 
0, inf, 1154.63733, inf, inf, inf, inf, inf, inf, inf, 1.14477244e+011, 

根据建议,删除了动态分配。新的输出看起来很漂亮,而且很有意义。接下来将规范化输入,并继续我的旅程。

{6120297, 4445404.5, 1772673.5, 1041102.38, 659743.438, 484291.75, 
513112.688, 289598.594, 668016.812, 487091.375, 315217.875, 585517.562, 
513285.281, 268263.375, 69867.4531, 108220.406, 85955.2031, 75381.0234, 
124448.68, 559070.812, 996484.75, 1008192.25, 515462.312, 316204.938, 
124825.734, 

标签: cembeddedsignal-processingcmsis

解决方案


推荐阅读