在音频采样应用吻FFT和获得NaN的输出? [英] Applying Kiss FFT on audio samples and getting NaN output?

查看:198
本文介绍了在音频采样应用吻FFT和获得NaN的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

标题解释了我的问题。

我所试图做的是非常简单的:

What I am trying to do is quite simple:


  • 加载MP3曲目(通过libmpg123)

  • 读取样本

  • 在样本应用吻FFT

我至今尝试过

inline float scale(kiss_fft_scalar val)
{
    int g = 0;
    return val < 0 ? val*(1/32768.0f ) : val*(1/32767.0f);
}

void main()
{
    mpg123_handle *m = NULL;
    int  channels = 0, encoding = 0;
    long rate = 0;
    int err = MPG123_OK;

    err = mpg123_init();        
    m = mpg123_new(NULL, &err);
    mpg123_open(m, "L:\\audio-io\\audio-analysis\\samples\\zero.mp3");
    mpg123_getformat(m, &rate, &channels, &encoding);

    err = mpg123_format_none(m);
    err = mpg123_format(m, rate, channels, encoding);

    // Get 2048 samples
    const int TIME = 2048;

    // 16-bit integer encoded in bytes, hence x2 size
    unsigned char* buffer = new unsigned char[TIME*2];
    size_t done = 0;
    err = mpg123_read(m, buffer, TIME*2, &done);

    short* samples = new short[done/2];
    int index = 0;

    // Iterate 2 bytes at a time
    for (int i = 0; i < done; i += 2)
    {
        unsigned char first = buffer[i];
        unsigned char second = buffer[i + 1];
        samples[index++] = (first | (second << 8));
    }

    // Array to store the calculated data
    int speclen = TIME / 2 + 1;
    float* output = new float[speclen];

    kiss_fftr_cfg config;
    kiss_fft_cpx* spectrum;

    config = kiss_fftr_alloc(TIME, 0, NULL, NULL);
    spectrum = (kiss_fft_cpx*) malloc(sizeof(kiss_fft_cpx) * TIME);

    // Right here...
    kiss_fftr(config, (kiss_fft_scalar*) samples, spectrum);

    for (int i = 0; i < speclen; i++)
    {
        float re = scale(spectrum[i].r) * TIME;
        float im = scale(spectrum[i].i) * TIME;

        output[i] = sqrtf(re*re + im*im);
    }

    return;
}

在此行中出现的问题 kiss_fftr(配置(kiss_fft_scalar *)样品,谱);
其中,样品包含音频样本(16位)和是假设保持输出数据。

The problem occurs at this line kiss_fftr(config, (kiss_fft_scalar*) samples, spectrum); Where samples contains the audio samples (16 bit), and spectrum is suppose to hold the output data.

功能完成后,这里发生的事情在调试器窗口。

After the function completes, here is what's happening in the debugger window.

有人可以给我如何申请吻FFT功能,音频(16位带codeD)样本一个简单的例子?

Can someone give me a simple example of how to apply Kiss FFT functions on audio (16 bit encoded) samples?

推荐答案

您需要找到您的code中的错误(S)。我的测试code似乎工作就好了。

You need to find the bug(s) in your code. My test code appears to work just fine.

复值正向FFT花车:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "kiss_fft.h"

#ifndef M_PI
#define M_PI 3.14159265358979324
#endif

#define N 16

void TestFft(const char* title, const kiss_fft_cpx in[N], kiss_fft_cpx out[N])
{
  kiss_fft_cfg cfg;

  printf("%s\n", title);

  if ((cfg = kiss_fft_alloc(N, 0/*is_inverse_fft*/, NULL, NULL)) != NULL)
  {
    size_t i;

    kiss_fft(cfg, in, out);
    free(cfg);

    for (i = 0; i < N; i++)
      printf(" in[%2zu] = %+f , %+f    "
             "out[%2zu] = %+f , %+f\n",
             i, in[i].r, in[i].i,
             i, out[i].r, out[i].i);
  }
  else
  {
    printf("not enough memory?\n");
    exit(-1);
  }
}

int main(void)
{
  kiss_fft_cpx in[N], out[N];
  size_t i;

  for (i = 0; i < N; i++)
    in[i].r = in[i].i = 0;
  TestFft("Zeroes (complex)", in, out);

  for (i = 0; i < N; i++)
    in[i].r = 1, in[i].i = 0;
  TestFft("Ones (complex)", in, out);

  for (i = 0; i < N; i++)
    in[i].r = sin(2 * M_PI * 4 * i / N), in[i].i = 0;
  TestFft("SineWave (complex)", in, out);

  return 0;
}

输出:

Zeroes (complex)
 in[ 0] = +0.000000 , +0.000000    out[ 0] = +0.000000 , +0.000000
 in[ 1] = +0.000000 , +0.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +0.000000 , +0.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = +0.000000 , +0.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +0.000000 , +0.000000    out[ 4] = +0.000000 , +0.000000
 in[ 5] = +0.000000 , +0.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +0.000000 , +0.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = +0.000000 , +0.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +0.000000 , +0.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +0.000000 , +0.000000    out[ 9] = +0.000000 , +0.000000
 in[10] = +0.000000 , +0.000000    out[10] = +0.000000 , +0.000000
 in[11] = +0.000000 , +0.000000    out[11] = +0.000000 , +0.000000
 in[12] = +0.000000 , +0.000000    out[12] = +0.000000 , +0.000000
 in[13] = +0.000000 , +0.000000    out[13] = +0.000000 , +0.000000
 in[14] = +0.000000 , +0.000000    out[14] = +0.000000 , +0.000000
 in[15] = +0.000000 , +0.000000    out[15] = +0.000000 , +0.000000
Ones (complex)
 in[ 0] = +1.000000 , +0.000000    out[ 0] = +16.000000 , +0.000000
 in[ 1] = +1.000000 , +0.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +1.000000 , +0.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = +1.000000 , +0.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +1.000000 , +0.000000    out[ 4] = +0.000000 , +0.000000
 in[ 5] = +1.000000 , +0.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +1.000000 , +0.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = +1.000000 , +0.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +1.000000 , +0.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +1.000000 , +0.000000    out[ 9] = +0.000000 , +0.000000
 in[10] = +1.000000 , +0.000000    out[10] = +0.000000 , +0.000000
 in[11] = +1.000000 , +0.000000    out[11] = +0.000000 , +0.000000
 in[12] = +1.000000 , +0.000000    out[12] = +0.000000 , +0.000000
 in[13] = +1.000000 , +0.000000    out[13] = +0.000000 , +0.000000
 in[14] = +1.000000 , +0.000000    out[14] = +0.000000 , +0.000000
 in[15] = +1.000000 , +0.000000    out[15] = +0.000000 , +0.000000
SineWave (complex)
 in[ 0] = +0.000000 , +0.000000    out[ 0] = +0.000000 , +0.000000
 in[ 1] = +1.000000 , +0.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +0.000000 , +0.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = -1.000000 , +0.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +0.000000 , +0.000000    out[ 4] = +0.000000 , -8.000000
 in[ 5] = +1.000000 , +0.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +0.000000 , +0.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = -1.000000 , +0.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +0.000000 , +0.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +1.000000 , +0.000000    out[ 9] = +0.000000 , +0.000000
 in[10] = +0.000000 , +0.000000    out[10] = +0.000000 , +0.000000
 in[11] = -1.000000 , +0.000000    out[11] = +0.000000 , +0.000000
 in[12] = +0.000000 , +0.000000    out[12] = +0.000000 , +8.000000
 in[13] = +1.000000 , +0.000000    out[13] = +0.000000 , +0.000000
 in[14] = +0.000000 , +0.000000    out[14] = +0.000000 , +0.000000
 in[15] = -1.000000 , +0.000000    out[15] = +0.000000 , +0.000000

实值FFT向前花车:

Real-valued forward FFT with floats:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "kiss_fftr.h"

#ifndef M_PI
#define M_PI 3.14159265358979324
#endif

#define N 16

void TestFftReal(const char* title, const kiss_fft_scalar in[N], kiss_fft_cpx out[N / 2 + 1])
{
  kiss_fftr_cfg cfg;

  printf("%s\n", title);

  if ((cfg = kiss_fftr_alloc(N, 0/*is_inverse_fft*/, NULL, NULL)) != NULL)
  {
    size_t i;

    kiss_fftr(cfg, in, out);
    free(cfg);

    for (i = 0; i < N; i++)
    {
      printf(" in[%2zu] = %+f    ",
             i, in[i]);
      if (i < N / 2 + 1)
        printf("out[%2zu] = %+f , %+f",
               i, out[i].r, out[i].i);
      printf("\n");
    }
  }
  else
  {
    printf("not enough memory?\n");
    exit(-1);
  }
}

int main(void)
{
  kiss_fft_scalar in[N];
  kiss_fft_cpx out[N / 2 + 1];
  size_t i;

  for (i = 0; i < N; i++)
    in[i] = 0;
  TestFftReal("Zeroes (real)", in, out);

  for (i = 0; i < N; i++)
    in[i] = 1;
  TestFftReal("Ones (real)", in, out);

  for (i = 0; i < N; i++)
    in[i] = sin(2 * M_PI * 4 * i / N);
  TestFftReal("SineWave (real)", in, out);

  return 0;
}

输出:

Zeroes (real)
 in[ 0] = +0.000000    out[ 0] = +0.000000 , +0.000000
 in[ 1] = +0.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +0.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = +0.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +0.000000    out[ 4] = +0.000000 , +0.000000
 in[ 5] = +0.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +0.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = +0.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +0.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +0.000000    
 in[10] = +0.000000    
 in[11] = +0.000000    
 in[12] = +0.000000    
 in[13] = +0.000000    
 in[14] = +0.000000    
 in[15] = +0.000000    
Ones (real)
 in[ 0] = +1.000000    out[ 0] = +16.000000 , +0.000000
 in[ 1] = +1.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +1.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = +1.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +1.000000    out[ 4] = +0.000000 , +0.000000
 in[ 5] = +1.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +1.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = +1.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +1.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +1.000000    
 in[10] = +1.000000    
 in[11] = +1.000000    
 in[12] = +1.000000    
 in[13] = +1.000000    
 in[14] = +1.000000    
 in[15] = +1.000000    
SineWave (real)
 in[ 0] = +0.000000    out[ 0] = +0.000000 , +0.000000
 in[ 1] = +1.000000    out[ 1] = +0.000000 , +0.000000
 in[ 2] = +0.000000    out[ 2] = +0.000000 , +0.000000
 in[ 3] = -1.000000    out[ 3] = +0.000000 , +0.000000
 in[ 4] = +0.000000    out[ 4] = +0.000000 , -8.000000
 in[ 5] = +1.000000    out[ 5] = +0.000000 , +0.000000
 in[ 6] = +0.000000    out[ 6] = +0.000000 , +0.000000
 in[ 7] = -1.000000    out[ 7] = +0.000000 , +0.000000
 in[ 8] = +0.000000    out[ 8] = +0.000000 , +0.000000
 in[ 9] = +1.000000    
 in[10] = +0.000000    
 in[11] = -1.000000    
 in[12] = +0.000000    
 in[13] = +1.000000    
 in[14] = +0.000000    
 in[15] = -1.000000    

这篇关于在音频采样应用吻FFT和获得NaN的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆