c64+ 的FFT问题
目前在研究FFT的问题。C64+有专门的FFT函数库: void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交织存放除最后一级外,每级的结果右移 1 并四舍五入void DSP_fft16x16r(int nx, short *x, short *w, short *y,int radix, int offset, int n_max)16 bits 复输入输出数据,复数按先实部/后虚部交织存放除最后一级外,每级的结果右移 1 并四舍五入针对比较小的 Cache 优化)
void DSP_fft32x32(int *w, int nx, int *x, int *y)32 bits 复输入输出数据,复数按先实部/后虚部交织存放32 bits 旋转因子。
void DSP_fft32x32s(int *w, int nx, int *x, int *y)32 bits 复输入输出数据,复数按先实部/后虚部交织存放32 bits 旋转因子除最后一级外,每级的结果右移 1
旋转因子(w)的产生是由tw_fft16x16 产生。现在问题来了,样才能结合它使用 DSP_fft16x16进行FFT变换。这个tw_fft16x16在库函数里面有.exe的应用程序,不知道怎么用。能不能给一个FFT变换的实例。求大神解答。
没有接触过希望用到的大神帮忙解答。 你把这几个函数的原版的函数说明贴出来看看! aresc 发表于 2015-7-25 22:04
你把这几个函数的原版的函数说明贴出来看看!
/* ======================================================================== */
/*TEXAS INSTRUMENTS, INC. */
/* */
/*NAME */
/* tw_fft16x16 */
/* */
/*USAGE */
/* This is a stand-alone program intended to generate twiddle-factor */
/* arrays for the DSP_fft, DSP_fft16x16r and DSP_fft16x16t FFT */
/* library routines.It is called as follows: */
/* */
/* tw_fft16x16 [-s scale] N > outputfile.c */
/* */
/* The argument 'N' specifies the size of the FFT.This value */
/* must be a power of 2.The switch '-s scale' allows selecting */
/* a different scale factor for the coefficients.The default */
/* scale factor is 32767.5. */
/* */
/* This program will generate the twiddle factor array 'w' and */
/* output the result to the display.Redirect the output to */
/* a file as shown above. */
/* */
/*DESCRIPTION */
/* This program contains the twiddle-factor generation routine */
/* that is described within the source code for the DSPLIB */
/* FFT functions DSP_fft16x16r and DSP_fft16x16t.It does not */
/* produce appropriate twiddle-factor arrays for the other FFT */
/* implementations. */
/* */
/* Please consult the specific FFT that you are using for details. */
/* */
/* The final twiddle-factor array generated by the routine will */
/* be 2 * N elements long. */
/* */
/*NOTES */
/* The code below may be adapted to run directly on the target, */
/* rather than running as a separate program running off-line. */
/* Such adaptation is not recommended for time-critical applications.*/
/* To adapt this program, remove the 'usage' and 'main' functions, */
/* and call 'gen_twiddle' directly. */
/* */
/* ------------------------------------------------------------------------ */
/* Copyright (c) 2001 Texas Instruments, Incorporated. */
/* All Rights Reserved. */
/* ======================================================================== */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifndef PI
# ifdef M_PI
#define PI M_PI
# else
#define PI 3.14159265358979323846
# endif
#endif
/* ======================================================================== */
/*D2S -- Truncate a 'double' to a 'short', with clamping. */
/* ======================================================================== */
static short d2s(double d)
{
if (d >=32767.0) return32767;
if (d <= -32768.0) return -32768;
return (short)d;
}
/* ======================================================================== */
/*GEN_TWIDDLE -- Generate twiddle factors for TI's custom FFTs. */
/* */
/*USAGE */
/* This routine is called as follows: */
/* */
/* int gen_twiddle(short *w, int n, double scale) */
/* */
/* short*w Pointer to twiddle-factor array */
/* int n Size of FFT */
/* double scaleScale factor to apply to values. */
/* */
/* The routine will generate the twiddle-factors directly into the */
/* array you specify.The array needs to be approximately 2*N */
/* elements long.(The actual size, which is slightly smaller, is */
/* returned by the function.) */
/* ======================================================================== */
int gen_twiddle(short *w, int n, double scale)
{
int i, j, k;
for (j = 1, k = 0; j < n >> 2; j = j << 2)
{
for (i = 0; i < n >> 2; i += j << 1)
{
w = d2s(scale * cos(6.0 * PI * (i + j) / n));
w = d2s(scale * sin(6.0 * PI * (i + j) / n));
w = d2s(scale * cos(6.0 * PI * (i ) / n));
w = d2s(scale * sin(6.0 * PI * (i ) / n));
w = d2s(scale * cos(4.0 * PI * (i + j) / n));
w = d2s(scale * sin(4.0 * PI * (i + j) / n));
w = d2s(scale * cos(4.0 * PI * (i ) / n));
w = d2s(scale * sin(4.0 * PI * (i ) / n));
w = d2s(scale * cos(2.0 * PI * (i + j) / n));
w = d2s(scale * sin(2.0 * PI * (i + j) / n));
w = d2s(scale * cos(2.0 * PI * (i ) / n));
w = d2s(scale * sin(2.0 * PI * (i ) / n));
k += 12;
}
}
return k;
}
/* ======================================================================== */
/*USAGE -- Print usage information and optionally an error message. */
/* ======================================================================== */
void usage(char *error)
{
fprintf(stderr,
" \n"
"USAGE \n"
" This is a stand-alone program intended to generate twiddle-factor \n"
" arrays for the DSP_fft, DSP_fft16x16r and DSP_fft16x16t FFT \n"
" library routines.It is called as follows: \n"
" \n"
" tw_fft16x16 [-s scale] N > outputfile.c \n"
" \n"
" The argument 'N' specifies the size of the FFT.This value \n"
" must be a power of 2.The switch '-s scale' allows selecting \n"
" a different scale factor for the coefficients.The default \n"
" scale factor is 32767.5. \n"
" \n"
" This program will generate the twiddle factor array 'w' and \n"
" output the result to the display.Redirect the output to \n"
" a file as shown above. \n"
" \n");
if (error)
fprintf(stderr, "ERROR:%s\n", error);
exit(1);
}
/* ======================================================================== */
/*MAIN -- Where the action happens. */
/* ======================================================================== */
int main(int argc, char *argv[])
{
int i, n = -1, size;
int is_pow_4 = 0;
short *w;
double scale = 32767.5;
char *s;
char buf;
/* -------------------------------------------------------------------- */
/*Parse the arguments. */
/* -------------------------------------------------------------------- */
if (argc < 2) { usage(NULL); }
while (argc-->1)
{
if (**++argv == '-' || **argv == '/')
{
switch (argv)
{
case 's' : case 'S' :
{
if (argv)
{
s = &argv;
} else
{
argc--;
s = *++argv;
}
if (!s || !*s || sscanf(s, "%lf", &scale) != 1)
usage("The -s switch requires a numeric argument.\n");
if (scale <= 0.0 || scale >32767.6)
usage("Scale factor out of range.\n");
break;
}
default:
{
sprintf(buf, "Unrecognized switch character: '%c'\n",
argv);
usage(buf);
break;
}
}
} else
{
if (!isdigit(argv) || sscanf(argv, "%d", &n) != 1)
{
sprintf(buf, "Unrecognized argument:%-.32s\n",
argv);
usage(buf);
}
if (n < 16 || n > 32768)
usage("FFT size must be between 16 and 32768 points.");
for (i = 2; i < 24; i++)
if ((1 << i) == n) break;
is_pow_4 = !(i & 1);
if (i >= 24)
{
usage("FFT size must be a power of 2\n");
exit(1);
}
}
}
if (n == -1)
usage("Must specify FFT size.");
/* -------------------------------------------------------------------- */
/*Allocate memory for the FFT twiddle factors. */
/* -------------------------------------------------------------------- */
w = calloc(2 * sizeof(short), n);
if (!w)
{
fprintf(stderr, "ERROR:Unable to allocate memory for "
"twiddle factors\n");
exit(1);
}
/* -------------------------------------------------------------------- */
/*Generate the twiddle-factor array. */
/* -------------------------------------------------------------------- */
size = gen_twiddle(w, n, scale);
/* -------------------------------------------------------------------- */
/*Print out the resulting twiddle factors. */
/* -------------------------------------------------------------------- */
printf(
"/* -------------------------------------------------------------------- */\n"
"/*Automatically generated twiddle-factor array. */\n"
"/* Number of points: %-5d */\n"
"/* Scale factor: %-20.9f */\n"
"/* Appropriate FFTs: DSP_fft16x16r, DSP_fft16x16t%s */\n"
"/* Required alignment:8 byte (double-word) */\n"
"/* -------------------------------------------------------------------- */\n",
n, scale, is_pow_4 ? ", DSP_fft" : " ");
printf("#pragma DATA_ALIGN(w, 8);\n");
printf("const short w =\n{", size / 2);
for (i = 0; i < size; i++)
{
printf("%s%c0x%.4X",
i == 0 ? "\n " : (i & 7) == 0 ? ",\n " : ", ",
w < 0 ? '-' : ' ', abs(w));
}
printf("\n};\n");
return 0;
}
aresc 发表于 2015-7-25 22:04
你把这几个函数的原版的函数说明贴出来看看!
DSP-fft的只有.h文件 所有FFT中的twiddle factor都是正弦、余弦表,但可能不同FFT的实现方法,具体的twiddle不一样。
那个默认的32767.5的用处是把[-1.0,1.0]的正弦、余弦值转成16位的定点整数而已。因为
static short d2s(double d)
{
if (d >=32767.0) return32767;
if (d <= -32768.0) return -32768;
return (short)d;
}
所以scale值不能超过2^16次方,
void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交织存放除最后一级外,每级的结果右移 1 并四舍五入
我不太明白 “除最后一级外,每级的结果右移 1 并四舍五入”,所以让你贴英文的函数说明看看。
另外short *y是个什么用处?难道不是同址运算?
aresc 发表于 2015-7-27 21:10
void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交 ...
谢谢~short*y 是输出的傅立叶变换数组地址。 我再贴一个 DSP_fft32x32(int *w, int nx, int *x, int *y)的说明,麻烦您再看看。有个问题:在使用我DSP_fft32x32(int *w, int nx, int *x, int *y)的时候,我如何知道*w呢,是调用gen_twiddle_fft32x32 这个函数产生一个数组吗或者其他? aresc 发表于 2015-7-27 21:10
void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交 ...
DSP_fft32x32
masege 发表于 2015-7-29 10:49
谢谢~short*y 是输出的傅立叶变换数组地址。 我再贴一个 DSP_fft32x32(int *w, int nx, int *x, int *y) ...
是的!
页:
[1]