?? acorr.c
字號:
/****************************************************************************
** $TITLE: ACORR.C$
** ACORR.C
** ---------
** Brings data in from the codec, and runs it through an Acorr algorithm.
** the data can be plotted in real time at the host or be sent to
** oscilloscope through the codec.
**
****************************************************************************/
/*--------------------------------------------------------------------------
EXTERNAL DECLARATIONS
--------------------------------------------------------------------------*/
extern volatile int user_tx_buf[6];
extern volatile int user_tx_ready;
extern volatile int user_rx_buf[6];
extern volatile int user_rx_ready;
/*--------------------------------------------------------------------------
INCLUDES
--------------------------------------------------------------------------*/
#include <def21060.h>
#include <21065l.h>
#include <signal.h>
#include <macros.h>
#include <limits.h>
#include <trans.h>
#include <float.h>
#include <math.h>
#include <ezkit/1819regs.h>
/*--------------------------------------------------------------------------
CONSTANT & MACRO DEFINITIONS
--------------------------------------------------------------------------*/
/* Number of sample points in the calculation */
#define NUM_POINTS 256
/* Codec tag word to send out left and right samples */
#define DOUT_TAG 0x9800
/* Codec tag word to send out address and data slots */
#define REGOUT_TAG 0xe000
/* This is the codec register setting for line input on both channels */
#define SOURCE_IS_LINE 0x0404
/* This is the codec register setting for mic input on both channels */
#define SOURCE_IS_MIC 0
/* Codec addreses */
#define SOURCE_ADDR 0x1a00
#define RECGAIN_ADDR 0x1c00
#define BETWEEN_SAMPLES 50000 /* Do fft every .5 secs @ 48 kHz */
/* The program can be in 1 of 3 modes. The other mode is a wait mode
and is anything greater than 2 */
#define SAMPLE_MODE 1
#define CALCULATE_MODE 2
#define CODEC_ISR_VECT 0X9001
/*--------------------------------------------------------------------------
GLOBAL DECLARATIONS
--------------------------------------------------------------------------*/
int data_count;
int out_count;
/* The output data is stored here */
int data[NUM_POINTS];
int mode; // mode 1 = collecting data points. mode 2 = calculating ACORR
/* Use this array for calculating the acorr, then copy result into data[] */
int tempdata[NUM_POINTS];
float result[NUM_POINTS];
/*--------------------------------------------------------------------------
FUNCTION PROTOTYPES
--------------------------------------------------------------------------*/
void main (void);
void sample_codec( void );
void init_codec( void );
/****************************************************************************
** Procedure: sample_codec()
**
** Arguments: None
**
** Returns: None
**
** Desc: Gets data in from the codec and sends the data or noise
** back out to the codec. If mode = SAMPLE_MODE, 128
** consecutive samples are taken from the codec for calculating
** the FFT.
**
****************************************************************************/
void sample_codec( void )
{
// Copy output buffers to transmit data buffers.
user_tx_buf[LEFT_CHANL] = data[out_count];
user_tx_buf[RIGHT_CHNL] = data[out_count];
out_count++;
if(out_count>=NUM_POINTS) out_count=0;
user_tx_buf[TAG] = DOUT_TAG;
user_tx_ready = 1;
//
if( mode == SAMPLE_MODE )
{
tempdata[data_count] = user_rx_buf[LEFT_CHANL];
data_count++;
/* If we have 128 samples, stop sampling and calculate */
if( data_count >= 128 )
{
data_count = 0;
mode = CALCULATE_MODE;
}
}
}
/****************************************************************************
**
** Procedure: init_codec()
**
** Arguments: None
**
** Returns: None
**
** Desc: Turns on the codec interrupt then initializes the codec
** source and record gain.
**
****************************************************************************/
void init_codec( void )
{
asm("#include <def21065l.h>");
interrupt(SIG_SPT1I,(void (*)(int))CODEC_ISR_VECT);
asm("BIT SET IMASK SPT1I;"); /* unmasks sport interrupt */
/* Set source to LINE */
user_tx_buf[TAG] = REGOUT_TAG;
user_tx_buf[ADDR] = SOURCE_ADDR;
user_tx_buf[DATA] = SOURCE_IS_LINE;
user_tx_ready = 1;
idle(); /* Wait for codec register to get set */
idle();
/* Set record gain */
user_tx_buf[TAG] = REGOUT_TAG;
user_tx_buf[ADDR] = RECGAIN_ADDR;
user_tx_buf[DATA] = 0;
user_tx_ready = 1;
idle(); /* Wait for codec register to get set */
idle();
return;
}
/****************************************************************************
**
** Procedure: main()
**
** Arguments: None
**
** Returns: None
**
** Desc: Sets everything up and then goes into its sampling and
** processing loop.
**
****************************************************************************/
void main ( void )
{
int i; /* counter variable */
int cntr; /* counter variable */
float fdata[NUM_POINTS]; /* array to convertg int points to floats */
int *optr;
float *fptr, *xptr, *yptr;
float fmin,fmax,favg,range;
int offset;
float scale_value;
data_count = 0;
out_count = 0;
mode = SAMPLE_MODE; /* Start with the first 128 samples */
init_codec(); /* Set up codec for line in */
for(;;) /* Start the sample/calculate/wait loop */
{
/* Just after accumulating the 128 points, calculate the FFT */
if( mode == CALCULATE_MODE )
{
optr = tempdata;
fptr = fdata;
/* to convertg int points to floats */
for( i=0 ; i<NUM_POINTS ; i++ )
{
*fptr++ = *optr++;
}
/* Acorr*/
/* Stage 1 */
fptr = result+NUM_POINTS/2-1;
for (cntr=0; cntr< NUM_POINTS/2; cntr++)
{
xptr=fdata;
yptr=fdata+cntr;
for( i=NUM_POINTS/2; i>0 ; i-- )
{
*fptr = *fptr + *xptr++ * *yptr++;
}
fptr++;
}
/* Stage 2 */
xptr=result+NUM_POINTS/2-2;
yptr=result+NUM_POINTS/2;
for( i=0 ; i<NUM_POINTS/2-1 ; i++ )
{
*xptr-- = *yptr++;
}
///////scale result///////////
offset = 50;scale_value = 25.0;
fmin = FLT_MAX;fmax = FLT_MIN;
favg = 0;
fptr = &result[0];
for( i=0 ; i<NUM_POINTS ; i++ )
{
fmax = fmax > *fptr ? fmax : *fptr;
fmin = fmin < *fptr ? fmin : *fptr;
favg += *fptr;
fptr++;
}
favg /= (NUM_POINTS - 2);
range = fmax - favg;
/* Copy data into output buffer - dont let host get data
right in the middle */
asm("#include <def21065l.h>");
asm volatile ("BIT CLR IMASK IRQ0I;");
fptr = result;
optr = data;
for( i=0 ; i<NUM_POINTS ; i++ )
{
*optr++ =150*( offset + (int)(scale_value * ( (*fptr++ - favg) / range )) );
}
for (cntr = 0; cntr < NUM_POINTS; cntr++)
{
tempdata[cntr]=0;
result[cntr]=0;
}
asm volatile ("BIT SET IMASK IRQ0I;");
}
/* Waiting.....,since the host can't sample that often anyway */
if (mode >= CALCULATE_MODE)
{
mode++;
if (mode >= BETWEEN_SAMPLES)
{
mode = SAMPLE_MODE;
}
}
user_rx_ready = 1; /* Tell codec isr we're ready for data */
while(user_rx_ready) idle(); /* Wait for codec data */
sample_codec(); /* Get data */
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -