home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1991 / 05 / bittman / ddj.c < prev    next >
C/C++ Source or Header  |  1991-02-10  |  12KB  |  269 lines

  1.  
  2. /*--- file: DDJ.C---------------------------------------------------
  3. |
  4. | DspHq interface to Numerical Recipes in C
  5. | BittWare Research Systems, Copyright 1990.
  6. |
  7. | souce code file:       ddj.c
  8. | function spec file:    ddj.fnc
  9. | parameter menu file:   ddj.mnu
  10. | dsp files:             dsp_32s.32c, dsp_32c.32c
  11. |
  12. | parameter list:
  13. |    parameter #    type      description
  14. |    -----------    ----      -----------
  15. |    1              hexword   buffer1, DSP board address
  16. |    2              hexword   buffer2, DSP board address
  17. |    3              float     Cosine Amplitude
  18. |    4              float     Cosine DC-Offset
  19. |    5              float     Cosine Frequency
  20. |    6              float     Cosine Sample-Rate
  21. |
  22. | function    input-list      output-list parameter-list
  23. | --------    ----------      ----------- --------------
  24. | gencos_pc   {}              {output1}   {n/a,n/a,amp,dco,freq,samp}
  25. | realft_pc   {}              {output1}   {}
  26. | irealft_pc  {}              {output1}   {}
  27. | logmag_pc   {input1}        {output1}   {}
  28. | gencos_32c  {}              {output1}   {buffer-1,n/a,amp,dco,freq,samp}
  29. | realft_32c  {input1}        {output1}   {buffer-1}
  30. | irealft_32c {input1}        {output1}   {buffer-1}
  31. | logmag_32c  {input1}        {output1}   {buffer-1, buffer-2}
  32. | rfft_32s    {input1}        {output1}   {buffer-1}
  33. | dl_float_32 {input1}        {}          {buffer-1}
  34. | ul_float_32 {}              {output1}   {buffer-1}
  35. |
  36. | Refer to DspHq and Numerical Recipes in C for further details.
  37. -------------------------------------------------------------------*/
  38.  
  39. /* include files */
  40. #include <stdio.h>              /* include for NULL define */
  41. #include <math.h>               /* include for math functions */
  42. #include "hq_ci_.h"             /* include for dsphq interface */
  43. #include "nr.h"                 /* include nr function prototypes */
  44. #include "nrutil.h"             /* include nr utility prototypes */
  45. #include "dsputil.h"            /* include CAC prototypes */
  46. #include "dspif.h"              /* dsp interface function header */
  47.  
  48.  
  49. /* define the menu parameter types */
  50. typedef unsigned long parm1_type;       /* Buffer 1 */
  51. typedef unsigned long parm2_type;       /* Buffer 3 */
  52. typedef menu_float    parm3_type;       /* Cosine Amplitude */
  53. typedef menu_float    parm4_type;       /* Cosine DC-offset */
  54. typedef menu_float    parm5_type;       /* Cosine Frequency */
  55. typedef menu_float    parm6_type;       /* Cosine Sammple Rate */
  56.  
  57.  
  58. /* constant definitions */
  59. #define SQR(a) ((a)*(a))
  60. #define PI               (float) 3.141592654
  61. #define BAD_FUNC_NUM     (int) -1       /* user error code */
  62.  
  63. /* FUNCTION CONSTANTS FOR DSP32 'C' & ASSEMBLY CODE */
  64. #define DSP32_X     1      /* converts IEEE ==> DSP numbers */
  65. #define IEEE32_X    2      /* converts DSP  ==> IEEE numbers */
  66.  
  67. /* FUNCTION CONSTANTS FOR DSP32 'C' CODE */
  68. #define GENCOS_C    3      /* generate test cosine */
  69. #define REALFT_C    4      /* performs realft, from numerical recipes */
  70. #define IREALFT_C   5      /* performs inv_realft, from numerical recipes */
  71. #define LOGMAG_C    6      /* calculates log-magnitude */
  72. #define RFFTA_C     7      /* calculates real fft using app-lib */
  73.  
  74. /* FUNCTION CONSTANTS FOR DSP32 ASSEMBLY CODE */
  75. #define RFFT_S      3      /* performs rfft, from AT&T application library */
  76. #define MAG_S       4      /* calculates magnitude-squared */
  77. #define LOG_S       5      /* calculates log */
  78.  
  79.  
  80. /*** function prototypes ***/
  81. int ilog2(unsigned int);
  82. void log_mag(float far * i1, float far * o1, long bs);
  83. void scale_data(float far *output1, float scale_val, long np);
  84. void synth_cos(float far *data1, long np, float a, float d, float f, float s);
  85.  
  86.  
  87. main(int argc, char *argv[])
  88. {
  89.    long                 indx;           /* used for loop index */
  90.    int                  func_num;       /* for function number from dsphq */
  91.    long                 np;             /* for block size from dsphq */
  92.    float far *          input1;         /* array address */
  93.    float far *          output1;        /* array address */
  94.    long                 bs;             /* address of DSP blocksize var */
  95.    long                 flag;           /* address of DSP funcnum flag */
  96.    parm1_type           b1;             /* DSP Buffer #1 */
  97.    parm2_type           b2;             /* DSP Buffer #2 */
  98.    parm3_type           amp;            /* cosine amplitude */
  99.    parm4_type           dco;            /* cosine DC offset */
  100.    parm5_type           freq;           /* cosine frequency */
  101.    parm6_type           samprate;       /* cosine sample rate */
  102.  
  103.    init_intfc(argc, argv);              /* init dsphq interface */
  104.    func_num = get_func_num();           /* get the function number */
  105.    np = get_block_size();               /* get the block size */
  106.  
  107.    /* get menu parameters */
  108.    b1 = get_parm(1);                    /* DSP Buffer #1 */
  109.    b2 = get_parm(2);                    /* DSP Buffer #2 */
  110.    amp = get_parm(3);                   /* cosine amplitude */
  111.    dco = get_parm(4);                   /* cosine DC offset */
  112.    freq = get_parm(5);                  /* cosine frequency */
  113.    samprate = get_parm(6);              /* cosine sample rate */
  114.  
  115.    /* get array addresses */
  116.    input1 = get_data_in_ptr(1);         /* base address of input #1 */
  117.    output1 = get_data_out_ptr(1);       /* base address of output #1 */
  118.  
  119.    /* perform selected function */
  120.    switch (func_num)
  121.    {
  122.       case 1 : /*** SYNTHESIZE COSINE USING PC ***/
  123.          synth_cos(output1, np, amp, dco, freq, samprate);
  124.          break;
  125.  
  126.       case 2 : /*** NUMERICAL RECIPES FORWARD REAL FFT USING PC ***/
  127.          output1--;                             /* NR funcs index at 1 */
  128.          realft(output1, np>>1, 1);             /* forward real fft */
  129.          break;
  130.  
  131.       case 3 : /*** NUMERICAL RECIPES INVERSE REAL FFT USING PC ***/
  132.          output1--;                             /* NR funcs index at 1 */
  133.          realft(output1, np>>1, -1);            /* inverse real fft */
  134.          output1++;                             /* reallign address */
  135.          scale_data(output1,1.0/(np >> 1),np);  /* restore original ampl. */
  136.          break;
  137.  
  138.       case 4 : /*** CALCULATE LOG(10)-[MAGNITUDE] USING PC ***/
  139.          if (input1)
  140.             log_mag(input1, output1, np);       /* take logmag of input */
  141.          else
  142.             log_mag(output1, output1, np);      /* perform logmag in-place */
  143.          break;
  144.  
  145.       case 5 : /*** SYNTHESIZE COSINE USING DSP-32C ***/
  146.          init_dsp("ddj_32c.32c",&flag,&bs,np);  /* download dsp code & init */
  147.          dsp_dl_fp(get_addr("amp"),amp);        /* download floats */
  148.          dsp_dl_fp(get_addr("dco"),dco);
  149.          dsp_dl_fp(get_addr("freq"),freq);
  150.          dsp_dl_fp(get_addr("samprate"),samprate);
  151.          set_dspbuf("o1", b1);                  /* set dsp buffer address */
  152.          dsp_dl_int(flag,GENCOS_C);             /* invoke function on dsp */
  153.          wait4dsp(flag);                        /* wait for dsp to finish */
  154.          ul_float(output1,np,flag,b1);          /* upload results */
  155.          break;
  156.  
  157.       case 6 : /*** NUMERICAL RECIPES FORWARD REAL FFT USING DSP-32C ***/
  158.          init_dsp("ddj_32c.32c",&flag,&bs,np);  /* download dsp code & init */
  159.          set_dspbuf("o1", b1);                  /* set dsp buffer address */
  160.          dl_float(input1,np,flag,b1);           /* download float array */
  161.          dsp_dl_int(flag,REALFT_C);             /* execute "realft" on dsp */
  162.          wait4dsp(flag);                        /* wait for dsp to finish */
  163.          ul_float(output1,np,flag,b1);          /* upload results */
  164.          break;
  165.  
  166.       case 7 : /*** NUMERICAL RECIPES INVERSE REAL FFT USING DSP-32C ***/
  167.          init_dsp("ddj_32c.32c",&flag,&bs,np);  /* download dsp code & init */
  168.          dl_float(input1,np,flag,b1);           /* download float array */
  169.          set_dspbuf("o1", b1);                  /* set dsp buffer address */
  170.          dsp_dl_int(flag,IREALFT_C);            /* execute "inv_realft" on dsp */
  171.          wait4dsp(flag);                        /* wait for dsp to finish */
  172.          ul_float(output1,np,flag,b1);          /* upload results */
  173.          break;
  174.  
  175.       case 8 : /*** CALCULATE LOG(10)-[MAGNITUDE] USING DSP-32C ***/
  176.          init_dsp("ddj_32c.32c",&flag,&bs,np);  /* download dsp code & init */
  177.          dl_float(input1,np,flag,b1);           /* download float array */
  178.          set_dspbuf("i1", b1);                  /* set dsp buffer address */
  179.          set_dspbuf("o1", b2);                  /* set dsp buffer address */
  180.          dsp_dl_int(flag,LOGMAG_C);             /* execute "inv_realft" on dsp */
  181.          wait4dsp(flag);                        /* wait for dsp to finish */
  182.          ul_float(output1,np,flag,b2);          /* upload results */
  183.          break;
  184.  
  185.       case 9 : /*** FORWARD REAL FFT USING DSP-32C APP-LIB ***/
  186.          init_dsp("ddj_32s.32c",&flag,&bs,np);  /* download dsp code & init */
  187.          dl_float(input1,np,flag,b1);           /* download float array */
  188.          set_dspbuf("o1", b1);                  /* set dsp buffer address */
  189.          dsp_dl_int(get_addr("stages"),ilog2(np));
  190.                                                 /* download int */
  191.          dsp_dl_int(flag,RFFT_S);               /* execute "rfft" on dsp */
  192.          wait4dsp(flag);                        /* wait for dsp to finish */
  193.          ul_float(output1,np,flag,b1);          /* upload results */
  194.          break;
  195.  
  196.       case 10: /*** DOWNLOAD DATA TO DSP-32C ***/
  197.          init_dsp("ddj_32s.32c",&flag,&bs,np);  /* download dsp code & init */
  198.          dl_float(input1,np,flag,b1);           /* download data from pc to dsp */
  199.          break;
  200.  
  201.       case 11: /*** UPLOAD DATA FROM DSP-32C ***/
  202.          init_dsp("ddj_32s.32c",&flag,&bs,np);  /* download dsp code & init */
  203.          ul_float(output1,np,flag,b1);          /* upload results */
  204.          break;
  205.  
  206.       default : set_err_return(BAD_FUNC_NUM); break;
  207.    }
  208. }
  209.  
  210. /*------------------------------------------------------------------
  211. | This function returns the integer part of the log base 2 of x.
  212. -------------------------------------------------------------------*/
  213. int ilog2(unsigned int x)
  214. {
  215.    return( x >> 1 ? 1 + ilog2(x >> 1) : 0);
  216. }
  217.  
  218. /*------------------------------------------------------------------
  219. | This function scales np elements of data1[] by scale_val.
  220. -------------------------------------------------------------------*/
  221. void scale_data(float far * data1, float scale_val, long np)
  222. {
  223.    long i;
  224.  
  225.    for (i = 0; i < np; i++)
  226.    {
  227.       data1[i] *= scale_val;
  228.    }
  229. }
  230.  
  231. /*------------------------------------------------------------------
  232. | This function generates cosine data:
  233. |    data[i] = A cos((2 pi f/s) i) + d
  234. -------------------------------------------------------------------*/
  235. void synth_cos(float far * data1, long np,
  236.                float a, float d, float f, float s)
  237. {
  238.    long i;
  239.    float theta, angle_step;
  240.  
  241.    angle_step = 2.0 * PI * f / s;
  242.    theta = 0.0;
  243.    for (i = 0; i < np; i++)
  244.    {
  245.       data1[i] = (a * cos(theta)) + d;
  246.       theta += angle_step;
  247.    }
  248. }
  249.  
  250. /*------------------------------------------------------------------
  251. | This function ???
  252. -------------------------------------------------------------------*/
  253. void log_mag(float far * i1, float far * o1, long bs)
  254. {
  255.    long i;
  256.    long n;
  257.  
  258.    n = bs >> 1;
  259.    o1[0] = log10(SQR(i1[0]));
  260.    for (i = 1; i < n; i++)
  261.    {
  262.       o1[i] = log10(SQR(i1[2*i]) + SQR(i1[2*i+1]));
  263.    }
  264.    for (i = n; i < bs; i++)
  265.    {
  266.       o1[i] = 0.0;
  267.    }
  268. }
  269.