home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1991
/
05
/
bittman
/
ddj.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-10
|
12KB
|
269 lines
/*--- file: DDJ.C---------------------------------------------------
|
| DspHq interface to Numerical Recipes in C
| BittWare Research Systems, Copyright 1990.
|
| souce code file: ddj.c
| function spec file: ddj.fnc
| parameter menu file: ddj.mnu
| dsp files: dsp_32s.32c, dsp_32c.32c
|
| parameter list:
| parameter # type description
| ----------- ---- -----------
| 1 hexword buffer1, DSP board address
| 2 hexword buffer2, DSP board address
| 3 float Cosine Amplitude
| 4 float Cosine DC-Offset
| 5 float Cosine Frequency
| 6 float Cosine Sample-Rate
|
| function input-list output-list parameter-list
| -------- ---------- ----------- --------------
| gencos_pc {} {output1} {n/a,n/a,amp,dco,freq,samp}
| realft_pc {} {output1} {}
| irealft_pc {} {output1} {}
| logmag_pc {input1} {output1} {}
| gencos_32c {} {output1} {buffer-1,n/a,amp,dco,freq,samp}
| realft_32c {input1} {output1} {buffer-1}
| irealft_32c {input1} {output1} {buffer-1}
| logmag_32c {input1} {output1} {buffer-1, buffer-2}
| rfft_32s {input1} {output1} {buffer-1}
| dl_float_32 {input1} {} {buffer-1}
| ul_float_32 {} {output1} {buffer-1}
|
| Refer to DspHq and Numerical Recipes in C for further details.
-------------------------------------------------------------------*/
/* include files */
#include <stdio.h> /* include for NULL define */
#include <math.h> /* include for math functions */
#include "hq_ci_.h" /* include for dsphq interface */
#include "nr.h" /* include nr function prototypes */
#include "nrutil.h" /* include nr utility prototypes */
#include "dsputil.h" /* include CAC prototypes */
#include "dspif.h" /* dsp interface function header */
/* define the menu parameter types */
typedef unsigned long parm1_type; /* Buffer 1 */
typedef unsigned long parm2_type; /* Buffer 3 */
typedef menu_float parm3_type; /* Cosine Amplitude */
typedef menu_float parm4_type; /* Cosine DC-offset */
typedef menu_float parm5_type; /* Cosine Frequency */
typedef menu_float parm6_type; /* Cosine Sammple Rate */
/* constant definitions */
#define SQR(a) ((a)*(a))
#define PI (float) 3.141592654
#define BAD_FUNC_NUM (int) -1 /* user error code */
/* FUNCTION CONSTANTS FOR DSP32 'C' & ASSEMBLY CODE */
#define DSP32_X 1 /* converts IEEE ==> DSP numbers */
#define IEEE32_X 2 /* converts DSP ==> IEEE numbers */
/* FUNCTION CONSTANTS FOR DSP32 'C' CODE */
#define GENCOS_C 3 /* generate test cosine */
#define REALFT_C 4 /* performs realft, from numerical recipes */
#define IREALFT_C 5 /* performs inv_realft, from numerical recipes */
#define LOGMAG_C 6 /* calculates log-magnitude */
#define RFFTA_C 7 /* calculates real fft using app-lib */
/* FUNCTION CONSTANTS FOR DSP32 ASSEMBLY CODE */
#define RFFT_S 3 /* performs rfft, from AT&T application library */
#define MAG_S 4 /* calculates magnitude-squared */
#define LOG_S 5 /* calculates log */
/*** function prototypes ***/
int ilog2(unsigned int);
void log_mag(float far * i1, float far * o1, long bs);
void scale_data(float far *output1, float scale_val, long np);
void synth_cos(float far *data1, long np, float a, float d, float f, float s);
main(int argc, char *argv[])
{
long indx; /* used for loop index */
int func_num; /* for function number from dsphq */
long np; /* for block size from dsphq */
float far * input1; /* array address */
float far * output1; /* array address */
long bs; /* address of DSP blocksize var */
long flag; /* address of DSP funcnum flag */
parm1_type b1; /* DSP Buffer #1 */
parm2_type b2; /* DSP Buffer #2 */
parm3_type amp; /* cosine amplitude */
parm4_type dco; /* cosine DC offset */
parm5_type freq; /* cosine frequency */
parm6_type samprate; /* cosine sample rate */
init_intfc(argc, argv); /* init dsphq interface */
func_num = get_func_num(); /* get the function number */
np = get_block_size(); /* get the block size */
/* get menu parameters */
b1 = get_parm(1); /* DSP Buffer #1 */
b2 = get_parm(2); /* DSP Buffer #2 */
amp = get_parm(3); /* cosine amplitude */
dco = get_parm(4); /* cosine DC offset */
freq = get_parm(5); /* cosine frequency */
samprate = get_parm(6); /* cosine sample rate */
/* get array addresses */
input1 = get_data_in_ptr(1); /* base address of input #1 */
output1 = get_data_out_ptr(1); /* base address of output #1 */
/* perform selected function */
switch (func_num)
{
case 1 : /*** SYNTHESIZE COSINE USING PC ***/
synth_cos(output1, np, amp, dco, freq, samprate);
break;
case 2 : /*** NUMERICAL RECIPES FORWARD REAL FFT USING PC ***/
output1--; /* NR funcs index at 1 */
realft(output1, np>>1, 1); /* forward real fft */
break;
case 3 : /*** NUMERICAL RECIPES INVERSE REAL FFT USING PC ***/
output1--; /* NR funcs index at 1 */
realft(output1, np>>1, -1); /* inverse real fft */
output1++; /* reallign address */
scale_data(output1,1.0/(np >> 1),np); /* restore original ampl. */
break;
case 4 : /*** CALCULATE LOG(10)-[MAGNITUDE] USING PC ***/
if (input1)
log_mag(input1, output1, np); /* take logmag of input */
else
log_mag(output1, output1, np); /* perform logmag in-place */
break;
case 5 : /*** SYNTHESIZE COSINE USING DSP-32C ***/
init_dsp("ddj_32c.32c",&flag,&bs,np); /* download dsp code & init */
dsp_dl_fp(get_addr("amp"),amp); /* download floats */
dsp_dl_fp(get_addr("dco"),dco);
dsp_dl_fp(get_addr("freq"),freq);
dsp_dl_fp(get_addr("samprate"),samprate);
set_dspbuf("o1", b1); /* set dsp buffer address */
dsp_dl_int(flag,GENCOS_C); /* invoke function on dsp */
wait4dsp(flag); /* wait for dsp to finish */
ul_float(output1,np,flag,b1); /* upload results */
break;
case 6 : /*** NUMERICAL RECIPES FORWARD REAL FFT USING DSP-32C ***/
init_dsp("ddj_32c.32c",&flag,&bs,np); /* download dsp code & init */
set_dspbuf("o1", b1); /* set dsp buffer address */
dl_float(input1,np,flag,b1); /* download float array */
dsp_dl_int(flag,REALFT_C); /* execute "realft" on dsp */
wait4dsp(flag); /* wait for dsp to finish */
ul_float(output1,np,flag,b1); /* upload results */
break;
case 7 : /*** NUMERICAL RECIPES INVERSE REAL FFT USING DSP-32C ***/
init_dsp("ddj_32c.32c",&flag,&bs,np); /* download dsp code & init */
dl_float(input1,np,flag,b1); /* download float array */
set_dspbuf("o1", b1); /* set dsp buffer address */
dsp_dl_int(flag,IREALFT_C); /* execute "inv_realft" on dsp */
wait4dsp(flag); /* wait for dsp to finish */
ul_float(output1,np,flag,b1); /* upload results */
break;
case 8 : /*** CALCULATE LOG(10)-[MAGNITUDE] USING DSP-32C ***/
init_dsp("ddj_32c.32c",&flag,&bs,np); /* download dsp code & init */
dl_float(input1,np,flag,b1); /* download float array */
set_dspbuf("i1", b1); /* set dsp buffer address */
set_dspbuf("o1", b2); /* set dsp buffer address */
dsp_dl_int(flag,LOGMAG_C); /* execute "inv_realft" on dsp */
wait4dsp(flag); /* wait for dsp to finish */
ul_float(output1,np,flag,b2); /* upload results */
break;
case 9 : /*** FORWARD REAL FFT USING DSP-32C APP-LIB ***/
init_dsp("ddj_32s.32c",&flag,&bs,np); /* download dsp code & init */
dl_float(input1,np,flag,b1); /* download float array */
set_dspbuf("o1", b1); /* set dsp buffer address */
dsp_dl_int(get_addr("stages"),ilog2(np));
/* download int */
dsp_dl_int(flag,RFFT_S); /* execute "rfft" on dsp */
wait4dsp(flag); /* wait for dsp to finish */
ul_float(output1,np,flag,b1); /* upload results */
break;
case 10: /*** DOWNLOAD DATA TO DSP-32C ***/
init_dsp("ddj_32s.32c",&flag,&bs,np); /* download dsp code & init */
dl_float(input1,np,flag,b1); /* download data from pc to dsp */
break;
case 11: /*** UPLOAD DATA FROM DSP-32C ***/
init_dsp("ddj_32s.32c",&flag,&bs,np); /* download dsp code & init */
ul_float(output1,np,flag,b1); /* upload results */
break;
default : set_err_return(BAD_FUNC_NUM); break;
}
}
/*------------------------------------------------------------------
| This function returns the integer part of the log base 2 of x.
-------------------------------------------------------------------*/
int ilog2(unsigned int x)
{
return( x >> 1 ? 1 + ilog2(x >> 1) : 0);
}
/*------------------------------------------------------------------
| This function scales np elements of data1[] by scale_val.
-------------------------------------------------------------------*/
void scale_data(float far * data1, float scale_val, long np)
{
long i;
for (i = 0; i < np; i++)
{
data1[i] *= scale_val;
}
}
/*------------------------------------------------------------------
| This function generates cosine data:
| data[i] = A cos((2 pi f/s) i) + d
-------------------------------------------------------------------*/
void synth_cos(float far * data1, long np,
float a, float d, float f, float s)
{
long i;
float theta, angle_step;
angle_step = 2.0 * PI * f / s;
theta = 0.0;
for (i = 0; i < np; i++)
{
data1[i] = (a * cos(theta)) + d;
theta += angle_step;
}
}
/*------------------------------------------------------------------
| This function ???
-------------------------------------------------------------------*/
void log_mag(float far * i1, float far * o1, long bs)
{
long i;
long n;
n = bs >> 1;
o1[0] = log10(SQR(i1[0]));
for (i = 1; i < n; i++)
{
o1[i] = log10(SQR(i1[2*i]) + SQR(i1[2*i+1]));
}
for (i = n; i < bs; i++)
{
o1[i] = 0.0;
}
}