打印

c64+ 的FFT问题

[复制链接]
2413|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
masege|  楼主 | 2015-7-24 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
目前在研究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变换的实例。求大神解答。






相关帖子

沙发
海中水| | 2015-7-24 17:49 | 只看该作者
没有接触过希望用到的大神帮忙解答。

使用特权

评论回复
板凳
aresc| | 2015-7-25 22:04 | 只看该作者
你把这几个函数的原版的函数说明贴出来看看!

使用特权

评论回复
地板
masege|  楼主 | 2015-7-26 23:55 | 只看该作者
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) return  32767;
    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 scale  Scale 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[k + 11] = d2s(scale * cos(6.0 * PI * (i + j) / n));
            w[k + 10] = d2s(scale * sin(6.0 * PI * (i + j) / n));
            w[k +  9] = d2s(scale * cos(6.0 * PI * (i    ) / n));
            w[k +  8] = d2s(scale * sin(6.0 * PI * (i    ) / n));

            w[k +  7] = d2s(scale * cos(4.0 * PI * (i + j) / n));
            w[k +  6] = d2s(scale * sin(4.0 * PI * (i + j) / n));
            w[k +  5] = d2s(scale * cos(4.0 * PI * (i    ) / n));
            w[k +  4] = d2s(scale * sin(4.0 * PI * (i    ) / n));

            w[k +  3] = d2s(scale * cos(2.0 * PI * (i + j) / n));
            w[k +  2] = d2s(scale * sin(2.0 * PI * (i + j) / n));
            w[k +  1] = d2s(scale * cos(2.0 * PI * (i    ) / n));
            w[k +  0] = 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[80];

    /* -------------------------------------------------------------------- */
    /*  Parse the arguments.                                                */
    /* -------------------------------------------------------------------- */
    if (argc < 2) { usage(NULL); }

    while (argc-->1)
    {
        if (**++argv == '-' || **argv == '/')
        {
            switch (argv[0][1])
            {
                case 's' : case 'S' :
                {
                    if (argv[0][2])
                    {
                        s = &argv[0][2];
                    } 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[0][1]);
                    usage(buf);
                    break;
                }
            }
        } else
        {
            if (!isdigit(argv[0][0]) || sscanf(argv[0], "%d", &n) != 1)
            {
                sprintf(buf, "Unrecognized argument:  %-.32s\n",
                        argv[0][0]);
                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[2 * %d] =\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;
}

使用特权

评论回复
5
masege|  楼主 | 2015-7-27 00:02 | 只看该作者
aresc 发表于 2015-7-25 22:04
你把这几个函数的原版的函数说明贴出来看看!

DSP-fft的只有.h文件

使用特权

评论回复
6
aresc| | 2015-7-27 21:04 | 只看该作者
所有FFT中的twiddle factor都是正弦、余弦表,但可能不同FFT的实现方法,具体的twiddle不一样。
那个默认的32767.5的用处是把[-1.0,1.0]的正弦、余弦值转成16位的定点整数而已。因为

static short d2s(double d)
{
     if (d >=  32767.0) return  32767;
     if (d <= -32768.0) return -32768;
     return (short)d;
}

所以scale值不能超过2^16次方,

使用特权

评论回复
7
aresc| | 2015-7-27 21:10 | 只看该作者
void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交织存放除最后一级外,每级的结果右移 1 并四舍五入

我不太明白 “除最后一级外,每级的结果右移 1 并四舍五入”,所以让你贴英文的函数说明看看。
另外short *y是个什么用处?难道不是同址运算?

使用特权

评论回复
8
masege|  楼主 | 2015-7-29 10:49 | 只看该作者
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 这个函数产生一个数组吗或者其他?

使用特权

评论回复
9
masege|  楼主 | 2015-7-29 10:53 | 只看该作者
aresc 发表于 2015-7-27 21:10
void DSP_fft16x16(short *w, int nx, short *x, short *y)16 bits 复输入输出数据,复数按先实部/后虚部交 ...

DSP_fft32x32

dsp FFT.rar

4.84 KB

32*32

使用特权

评论回复
10
aresc| | 2015-7-29 22:33 | 只看该作者
masege 发表于 2015-7-29 10:49
谢谢~short*y 是输出的傅立叶变换数组地址。 我再贴一个 DSP_fft32x32(int *w, int nx, int *x, int *y) ...

是的!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

24

帖子

0

粉丝