繁体   English   中英

16位短(实际)跨步数据的FFT

[英]FFT of 16 bit short (real) strided data

我需要计算这样存储的2个短数据阵列的FFT(复制毫秒次): 内存中的数据分布 等等。

数组值由黄色和蓝色表示。 每个K值都有一个我需要跳过的未使用数据的K空间。

我重新排序(并浮动)数据以摆脱无用的值并使用FFTW(用c)来计算所需的变换。

关于这个过程我有两个问题。

  1. 有没有办法使用inistrideidist参数(如文档中所示 )按原样使用数组(没有重新排序,只能转换为浮点数)? 我想没有,但也许我已经烧光了。
  2. 是否有任何好的库可以使用短数据作为输入来计算fft? 我会很高兴交易一些精确的加速。 此代码将在i7上运行。

我是Mark Borgerding对KISS FFT非常满意的用户。 它具有整数变换,并且它还具有纯实变换,该变换利用专有实值输入变换中固有的Hermitian对称性来减少所需的计算次数。

但是,您需要自己跟踪数据位置。 该接口非常简单,只需一个指向内部数据缓冲区以及输入和输出缓冲区地址的指针。

假设您的输入是实值的,您可以执行以下操作:

//Must compile with -DFIXED_POINT=16 directive,
//to tell kiss_fft to do fixed-point transforms with short int data

#include "kiss_fft.h"
#include "kiss_fftr.h"

const size_t K = ...;
const size_t inSize = K/6; //6 based on your diagram above, adjust as needed

kiss_fft_scalar *inBuf = bigInputBuffer;
kiss_fft_cpx outBuf[1+inSize/2]; //Hermitian symmetry, so DC + N/2 complex outputs
//kiss_fft_cpx outBuf[inSize]; //if not using the real transform
size_t ctr = 0;

kiss_fftr_cfg fftCfg = kiss_fftr_alloc(inSize, false, NULL, NULL);
//kiss_fft_cfg fftCfg = kiss_fft_alloc(inSize, false, NULL, NULL); //if not using the real transform

do {
  kiss_fftr(fftCfg, inBuf, outBuf); //kiss_fft(...) is not using the real transform
  //do something with outBuf
  ++ctr;
  if (ctr == 6) {
    inBuf += K;
    ctr = 0;
  } else {
    inBuf += K/6;
  }
} while ((inBuf - bigInputBuffer) < bigBufSize);

注意事项:

  • 您需要重新编译才能更改数据类型。 对于short或int数据,请使用FIXED_POINT=16FIXED_POINT=32 ,或者不要将FIXED_POINT设置为执行浮点变换。
  • FIXED_POINT在源中必须具有相同的值, FIXED_POINT kiss_fft.*kiss_fftr.* 所以要么在所有文件中手动设置,要么(更好)使用-D将其作为编译器指令传递,例如, clang -DFIXED_POINT=16 kiss_fft.c kiss_fftr.c main.c
  • 实数转换期望输入缓冲区大小为偶数。
  • 转换期望输入缓冲区的大小为2,3,5的乘积。 我不记得它是否适用于其他尺寸,但即使这样做也会很慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM