gentable.c

来自「realview22.rar」· C语言 代码 · 共 288 行

C
288
字号
/*
 * $Copyright: 
 * ----------------------------------------------------------------
 * This confidential and proprietary software may be used only as
 * authorised by a licensing agreement from ARM Limited
 *   (C) COPYRIGHT 1999,2000,2002 ARM Limited
 *       ALL RIGHTS RESERVED
 * The entire notice above must be reproduced on all authorised
 * copies and copies may only be made to the extent permitted
 * by a licensing agreement from ARM Limited.
 * ----------------------------------------------------------------
 * File:     gentable.c,v
 * Revision: 1.9
 * ----------------------------------------------------------------
 * $
 *
 * Create the trigonometry tables needed for FFT's
 *
 */

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

void generate_tables(FILE *fp);
void generate_table_data(FILE *fp, int Q, char format);
void output(FILE *fp, int Q, double val);
int round(double a);
static int count;

#define MAXSTAGES 20
int stage[MAXSTAGES];
int nStages;
char stagesString[64];
int N;

int main(int argc, char **argv)
{
  int i,n;
  char path[256];
  FILE *fp;
  int repeat=1;
  
  /* check that round() does the correct thing for this compiler */
  assert(round(0.3)==0);
  assert(round(0.7)==1);
  assert(round(-0.3)==0);
  assert(round(-0.7)==-1);

  while (repeat) {
    nStages=0;
    
    /* read command line argumnets */
    if (--argc>0) {
      N = atoi(*(++argv)); 
      while (--argc>0) {
        stage[nStages++] = atoi(*(++argv));
      }
      repeat=0;
    } else {
      printf("Please enter the maximum FFT size to generate twiddle tables.\n");
      printf("Please enter 0 to generate the radix tabels t_rad.c\n");
      scanf(" %d", &N);
      printf("Please enter any specified radix stages (finish with zero):\n");
      while (1) {
        int R;
          
        scanf("%d", &R);
        if (R==0) break;
        stage[nStages++] = R;
      }
    }
    
    if (N) {
      printf("\nMaximum FFT size = %d\n", N);
    } else {
      printf("Generating radix tables\n");
    }
    
    /* print out the specified stages */
    n=N;
    stagesString[0]=0;
    printf("Specified stages:");
    for (i=0; i<nStages; i++) {
      int R = stage[i];
      
      printf(" %d", R);
      sprintf(stagesString+strlen(stagesString), "_%d", R);
      if (n%R!=0) {
        printf("\nError: This stage does not divide the remainder: %d\n", n);
        exit(1);
      }
      n = n/R;
    }
    printf("\n");
    
    /* now work out the assumed stages */
    printf("Assumed stages:  ");
    while (n>1) {
      int R;
      
      if (n&1) {
        printf("Odd n not yet supported: %d\n",n);
        exit(1);
      }
      if (n&2) {
        R=2;
      } else {
        R=4;
      }
      printf(" %d", R);
      if (nStages==0) sprintf(stagesString+strlen(stagesString), "_%d", R);
      stage[nStages++] = R;
      n=n/R;
    }
    printf("\n");
  
    /* formulate filename */
    if (N) sprintf(path, "t_%05d%s.c", N, stagesString);
    else   sprintf(path, "t_rad.c");
        
    printf("Output file = %s\n", path);
    fp = fopen(path, "wt");
    if (fp == NULL) {
      printf ("Couldn't open file %s for output.\n", path);
      exit (1);
    }
  
    fprintf(fp, "/*\n");
    fprintf(fp, " * Copyright (C) ARM Limited 1998-2002. All rights reserved.\n");
    fprintf(fp, " *\n");
    fprintf(fp, " * %s\n", path);
    fprintf(fp, " *\n");
    fprintf(fp, " */\n\n");
    
    generate_tables(fp);
        
    fclose (fp);
  
    printf ("Tables created\n");
  }
  return 0;
}

void generate_tables(FILE *fp) {
  generate_table_data(fp, 14, 'S');
  generate_table_data(fp, 30, 'S');
  generate_table_data(fp, 14, 'R');
  generate_table_data(fp, 30, 'R');
}

void generate_table_data(FILE *fp, int Q, char format)
{
  double pi, t;
  int n,j,l,ss,Size;
  char formatString[64];
  
  printf("Generating table: Q%d%c\n", Q, format);
  pi = 4.0 * atan (1.0);
  
  switch (Q) {
    case 14: sprintf(formatString, "const unsigned short t_Q14%c", format); break;
    case 30: sprintf(formatString, "const int t_Q30%c", format); break;
  }
  
  if (N==0) {
    /* generate radix tables */
    for (j=0; j<nStages; j++) {
      n = stage[j];
      Size = (n/4)-1;
      fprintf(fp, "extern %s_rad%d[%d];\n", formatString, n, 2*Size);
      fprintf(fp, "%s_rad%d[%d] = {", formatString, n, 2*Size);
      t = 2.0*pi/(double)n;
      count=0;
      for (l=1; l<n/4; l++) {
        double a,c,s;
        
        a = (double)l*t;
        c = cos(a);
        s = sin(a);
        if (format=='S') {
          output(fp, Q, c-s);
        } else {
          output(fp, Q, c);
        }
        output(fp, Q, s);
        Size--;
      }
      fprintf(fp, "};\n\n");
      assert(Size==0);
    }
    return;
  }
  
  fprintf(fp, "extern const int s_Q%d%c%s;\n", Q, format, stagesString);
  fprintf(fp, "const int s_Q%d%c%s = %d;\n", Q, format, stagesString, N);
  n=stage[0];
  Size = N-n;
  fprintf(fp, "extern %s%s[%d];\n", formatString, stagesString, 2*Size);
  fprintf(fp, "%s%s[%d] = {\n", formatString, stagesString, 2*Size);
  count = 0;
  
  for (j=1; j<nStages; j++) {
    int nn;
    int R;
    
    R = stage[j];
    nn = n*R;
    t = 2.0*pi/(double)nn;
    for (l=0; l<n; l++) {
      for (ss=1; ss<R; ss++) {
        double c,s,a;
        int r=ss;
        
        if (R==4) {
          if (r<3) r^=3; /* bit reverse r */
        }
        
        a = (double)(l*r)*t;
        c = cos(a);
        s = sin(a);
        if (format=='S') {
          output(fp, Q, c-s);
        } else {
          output(fp, Q, c);
        }
        output(fp, Q, s);
        Size--;
      }
    }
    n = nn;
  }
  fprintf(fp, "};\n\n");
  assert(Size==0);
}

void output(FILE *fp, int Q, double val) {
  int v;
  
  switch (Q) {
    case 14: /* short */
      v = round(val * (double)(1<<14));
      assert(v<0x7FFF && v>=-0x8000);
      if (count==0)
      {
        fprintf(fp, "  0x%04x", v & 0xffff);
      }
      else
      {
        fprintf(fp, ",0x%04x", v & 0xffff);
      }
      break;
    case 30: /* word */
      v = round(val * (double)(1UL<<30));
      if (count==0)
      {
        fprintf(fp, "  0x%08x", v);
      }
      else
      {
        fprintf(fp, ",0x%08x", v);
      }
      break;
    default:
      printf("Error: output() called with Q = %d\n", Q);
      exit(1);
  }
  if (count&1)
  {
    fprintf(fp," ");
  }
  count++;
  
  if (count==6) {
    fprintf(fp, ",\n");
    count=0;
  }
}

int round(double a) {
  if (a>=0) {
    return (int)(a+0.5);
  }
  return (int)(a-0.5);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?