📄 tw_r2fft.c
字号:
/* ======================================================================== */
/* TEXAS INSTRUMENTS, INC. */
/* */
/* NAME */
/* tw_r2fft */
/* */
/* USAGE */
/* This is a stand-alone program intended to generate twiddle-factor */
/* arrays for the DSPF_sp_cfftr2_dit FFT library routine. It is called*/
/* as follows: */
/* */
/* tw_r2fft N > outputfile.c */
/* */
/* The argument 'N' specifies the size of the FFT. This value */
/* must be a power of 2. */
/* */
/* This program will generate the twiddle factor array 'w', */
/* bit-reverse 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 function DSPF_sp_cfftr2_dit. 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) 2003 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
/* ======================================================================== */
/* */
/* TEXAS INSTRUMENTS, INC. */
/* */
/* NAME */
/* bit_rev */
/* */
/* USAGE */
/* This function has the prototype: */
/* */
/* void bit_rev(float *x, int n); */
/* */
/* x : Array to be bit-reversed. */
/* n : Number of complex array elements to bit-reverse. */
/* */
/* DESCRIPTION */
/* This routine bit reverses the floating point array x which */
/* is considered to be an array of complex numbers with the even */
/* numbered elements being thr real parts of the complex numbers */
/* while the odd numbered elements being the imaginary parts of the */
/* complex numbers. This function is made use of in sp_icfftr2_dif */
/* to bit-reverse the twiddle factor array generated using */
/* tw_genr2fft.c. */
/* ======================================================================== */
void bit_rev(float* x, int n)
{
int i, j, k;
float rtemp, itemp;
j = 0;
for(i=1; i < (n-1); i++)
{
k = n >> 1;
while(k <= j)
{
j -= k;
k >>= 1;
}
j += k;
if(i < j)
{
rtemp = x[j*2];
x[j*2] = x[i*2];
x[i*2] = rtemp;
itemp = x[j*2+1];
x[j*2+1] = x[i*2+1];
x[i*2+1] = itemp;
}
}
}
/* ======================================================================== */
/* GEN_TWIDDLE -- Generate twiddle factors for TI's custom FFTs. */
/* */
/* USAGE */
/* This routine is called as follows: */
/* */
/* int tw_r2fft (float *w, int n) */
/* */
/* float *w Pointer to twiddle-factor array */
/* int n Size of FFT */
/* */
/* The routine will generate the twiddle-factors directly into the */
/* array you specify. The array needs to be N elements long. */
/* ======================================================================== */
int gen_twiddle(float *w, int n)
{
double delta = 2 * PI / n;
int i;
for(i = 0; i < n/2; i++)
{
w[2 * i + 1] = sin(i * delta);
w[2 * i] = cos(i * delta);
}
return n;
}
/* ======================================================================== */
/* 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_radix2 library routine. It is called as follows:\n"
" \n"
" tw_r2fft N > outputfile.c \n"
" \n"
" The argument 'N' specifies the size of the FFT. This value \n"
" must be a power of 2. \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, is_pow_2;
float *w;
char *s;
char buf[80];
/* -------------------------------------------------------------------- */
/* Parse the arguments. */
/* -------------------------------------------------------------------- */
if (argc < 2) { usage(NULL); }
while (argc-->1)
{
if (!isdigit(argv[1][0]) || sscanf(argv[1], "%d", &n) != 1)
{
sprintf(buf, "Unrecognized argument: %-.32s\n",
argv[1][0]);
usage(buf);
}
if (n < 8 || n > 16384)
usage("FFT size must be between 8 and 16384 points.");
for (i = 2; i < 24; i++)
if ((1 << i) == n) break;
is_pow_2 = !(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(float), 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);
bit_rev(w, n>>1);
/* -------------------------------------------------------------------- */
/* Print out the resulting twiddle factors. */
/* -------------------------------------------------------------------- */
printf(
"/* -------------------------------------------------------------------- */\n"
"/* Automatically generated twiddle-factor array. */\n"
"/* Number of points: %-5d */\n"
"/* Appropriate FFTs: DSPF_sp_cfftr2_dit, DSPF_sp_icfftr2_dif */\n"
"/* Required alignment: 8 byte (word) */\n"
"/* -------------------------------------------------------------------- */\n"
"/* NOTE: It is suggested that this array be aligned in a different */\n"
"/* starting bank than the actual FFT data, to reduce bank conflicts. */\n"
"/* This can be achieved by using the DATA_MEM_BANK pragma. Please */\n"
"/* see the TMS320C6000 Optimizing C Compiler Reference (SPRU187E) */\n"
"/* for details on \"#pragma DATA_MEM_BANK\". */\n"
"/* -------------------------------------------------------------------- */\n"
"\n"
"#pragma DATA_ALIGN(w, 8); /* Remove this if using DATA_MEM_BANK */\n"
"\n", n);
printf("const float w[2 * %d] =\n{", size / 2);
for (i = 0; i < size; i++)
{
printf("%s%c%f",
i == 0 ? "\n " : (i & 7) == 0 ? ",\n " : ", ",
w[i] < 0 ? '-' : ' ', fabs(w[i]));
}
printf("\n};\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -