⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 src.c

📁 在blankfin中 实现src 的程序
💻 C
字号:
/****************************************************************************
*	File:		SRC.c
*	Date:		Sept 26 2002
*   Created:	Jeff Sondermeyer
****************************************************************************/

/*
(C) Copyright 2002 - Analog Devices, Inc.  All rights reserved.

File Name:		SRC.c

Date Modified:	9/27/02		Jeff Sondermeyer		Rev 0.2

Purpose:	  	The Sample Rate Converter (SRC) and Main Program Shell Developed using the ADSP-21535 EZ-KIT Lite
				Evaluation Platform.               
										  
				This C shell contains function calls and routines to initialize the state of the 21535 as well as the SRC.

				This program assumes input data comes from a 16-bit buffer (initialized as 'x' in this shell).  This data is 
				copied into a 32-bit buffer 'in1' within src_flt.asm.  At the end of src_flt.asm, the last 32-bit 
				buffer 'inx' (where 'x' is the last stage) is copied into a 16-bit buffer ('y' in this shell).  These 
				16-bit input/output buffers can be eliminated to conserve data space.  In this case, you will need to 
				undefine 'BUFIN' and preload 'in1' with 32-bit data and then use the 32-bit output data from 'inx'.
			
				The converter was designed to convert between any of the following rates:
				48000, 44100, 32000, 22050, 16000, 11025, and 8000.  If you have the SRC program from Momentum Data
				Systems you can generate coefficients for any SRC.  Follow #3 below.

				The #2 workspace in this project has all the necessary plots of the input/output stages as well in the
				intermediate buffers.  You can look at the data in the time domain or apply the built-in FFT plotting
				function to analyze	the frequency domain.  Load "plots_xxxxtoxxxx.vdw" for a particular SRC.

				I have generated a "SINE_xxxxx_16bit_1024.dat" input file to test every SRC.  This is a 16-bit, 1024-sample, 1KHz
				sine wave at the input sample rate.  These were generated using MATLAB (see 'gen_sine_wave_comma_16.m'). 
				It's easy to verify proper conversion by counting samples in one period at both the input rate (in the 'x' 
				plot) and the output rate (in the 'y' plot) in workspace #2.

Notes: 			1. You can modify the size of NINPS and NOUTS in each 'src_xxxxtoxxxx.h' file.  However, it MUST be the
				same multiple of the GCD.

				2. Buffer sizes, NINPS and NOUTS must be at least half of the filter coefficient sizes times the INTPx
				value to ensure	valid output data.

				3. Do the following to convert the decimal filter coefficients from Momentum Data Systems SRC *.dsp
				file to properly format this data as 32-bit Hexidecimal value.  This is then read into the 
				corresponding variable at initialization:
					a. Use Excel to import the *.dsp file (space delimited).  Select the "D" column and erase
					   everything else.  Save the file as a "Formatted Text (Space Delimited)(*.prn)" file.
					b. Use the MATLATB program "dec_file_to_hex_file_converter.m".  This MATLAB program 
					   will read in decimal (exponential) data from a file (*.prn) and convert to a 32-bit 
					   Hexidecimal format (*.dat file) suitable to be read by VisualDSP within a data 
					   initialization section.

				4. When 'BUFIN' is undefined, the program assumes that 'in1' is preloaded with 32-bit input data AFTER the 
				src_init is accomplished (buffer zeroing).  This requires that the shell program preload 'in1' from a 32-bit 
				source.  Define 'BUFIN' to include the 16-bit buffer transfer code within src_flt.asm.	x and y 16-bit
				buffers are nice but is just another chunk of memory that is necessary.

				5. To "zero" out filter delays, use the following equations as offsets to first valid data:
					1st Offset = (LENG1-1)/(2*DOWN1)
					2nd Offset = INTP2/DOWN2*1st Offset + (LENG2-1)/(2*DOWN2)
					3rd Offset = INTP3/DOWN3*2nd Offset + (LENG3-1)/(2*DOWN3)
				See the constants generated in the 'src_xxxxtoxxxx.h' files.
					
				6. DOFSx (in src_xxxxtoxxxx.h) is the offset and also is the number of valid output data samples.  This will allow
				you to figure how often this routine needs to be executed in a block-processed system.  Be careful with this number.
				The preprocessor in VDSP will not generate fractional constants.  Therefore, depending on the math here, DOFSx 
				could have an error of +/-1.  For a particular SRC, check the first sample in 'y' and adjust the DOFSx accordingly.

				7. One idea of reducing the number of intermediate buffers is to call a 'zero_buf' function that would rezero
				the buffers between filter sections.  This would reduce the number of intermediate buffers to two at the expense
				of more MIPs.  However, the MIPs increase would be negligable and is on the order of the size of the buffer.  These
				two intermediate buffers should be sized to the maximum needed for any SRC.

				8. If there is a big interpolation constant, this severely reduces the number of valid data samples in the
				final output buffer.  For example, in the 44.1K to 48K case, there is an interpolation constant of 16 in the 3rd stage.
				If we only use L1 data sections (max = 4096 bytes) we only get 111 valid data samples in the final output buffer.
				However, if I use L2 and make this intermediate buffer as large as 4096 words (16K bytes), I can get a relatively
				large number of valid output data samples.  The point here is that.. depending on interpolation constants, the limiting
				factor appears to be the L1 section size.  I can maximize all my filters based on this L1 section size (4096 bytes or 1024
				words) ...OR..  assume someone can use L2 and make the intermediate buffers larger.  In the later case, the number of VALID
				output data samples greatly increases.

				9. The half band code was not implemented.  Therefore, the HALFB define is not used.

				10. 11025to16, 16to2204, and 8to11025 produced corrupted data with 3-stage filters.  Had to use 2-stages.  MDS filter
				generator produces corrupted 3rd stage output for close sample rate conversions that required up sampling???  Not sure why.
				
				11. The latest revision of the code was debugged on a Momentum Systems Hawk PCI board.  All FileIO was done over the PCI bus.  
				Several things need to change in this code to work with the Hawk board:
				a. Define 'HAWK'
				b. Add idle.c and the basiccrt.s file for the Hawk board to the project.


*/

/* ------------------------------------------------------------------------ */
#include "fract_math.h"
#include <defBF535.h>
#include "src_inc.h"
#include "src_441to48.h"
#include <stdlib.h>
#include <stdio.h>

//#define HAWK

#ifdef HAWK
#include <device.h>
#endif



/* ------------------------------------------------------------------------ */

// 16-bit input/output buffers


static segment("L1_data_b") 
short x[NINPS];

static segment("L1_data_b") 
short y[NOUTS];


FILE *inFile,*outFile;


// 32-bit intermediate buffers

segment("L1_data_a")  
int in1[SZIN1];

segment("L1_data_a") 
int in2[SZIN2]; 


#if STAGE>=2
segment("L1_data_a") 
int in3[SZIN3]; 
#endif

#if STAGE==3
segment("L1_data_a") 
int in4[SZIN4]; 
#endif


// Filter Coefficients


static segment("L1_data_b")  
int filter_h1[MLEN1] = 
{
#include "441to48_32bit_flt1.dat"
};

#if STAGE>=2
static segment("L1_data_b") 
int filter_h2[MLEN2] =  
{
#include "441to48_32bit_flt2.dat"
};
#endif

#if STAGE==3
static segment("L1_data_b") 
int filter_h3[MLEN3] =  
{
#include "441to48_32bit_flt3.dat"
};
#endif


#ifdef HAWK
///////////////////////////////////////////////////////////////////
// This line enables the PCI as the default device for file I/O  
#pragma retain_name
extern int __default_io_device = PCI_IO;
						     
///////////////////////////////////////////////////////////////////
#endif

/* ------------------------------------------------------------------------ */

static void init_first_stage(STAGE_HANDLE *S) {

 FIRST_STAGE_ENTRY *V;

 V = S->V;
 V->in_s = &in1[0];
 V->in_z = SZIN1;
 V->out_s = &in2[0];
 V->out_z = SZIN2;
V->h = &filter_h1[0];
 V->plen = PLEN1-1;
 V->up = INTP1;
 V->dn = DOWN1;
 V->nis = NINP1;
 V->nos = NINP2;
 V->nshft = SHFT1;
 V->in_c = &in1[0];
 V->out_c = &in2[0];
 
}

#if STAGE>=2
static void init_sec_stage(STAGE_HANDLE *S) {

 SEC_STAGE_ENTRY *M;

 M = S->M;
 M->in_s = &in2[0];
 M->in_z = SZIN2;
 M->out_s = &in3[0];
 M->out_z = SZIN3;
 M->h = &filter_h2[0];
 M->plen = PLEN2-1;
 M->up = INTP2;
 M->dn = DOWN2;
 M->nis = NINP2;
 M->nos = NINP3;
 M->nshft = SHFT2;
 M->in_c = &in2[0];
 M->out_c = &in3[0];
}
#endif

#if STAGE==3

static void init_last_stage(STAGE_HANDLE *S) {

 THIRD_STAGE_ENTRY *L;

 L = S->L;
 L->in_s = &in3[0];
 L->in_z = SZIN3;
 L->out_s = &in4[0];
 L->out_z = SZIN4;
 L->h = &filter_h3[0];
 L->plen = PLEN3-1;
 L->up = INTP3;
 L->dn = DOWN3;
 L->nis = NINP3;
 L->nos = NINP4;
 L->nshft = SHFT3;
L->in_c = &in3[0];
 L->out_c = &in4[0];
 }
#endif


/* ------------------------------------------------------------------------ */

static segment("L1_data_b")  
FIRST_STAGE_ENTRY vst;
static segment("L1_data_b")  
SEC_STAGE_ENTRY mst;
static segment("L1_data_b")  
THIRD_STAGE_ENTRY lst;
static segment("L1_data_b")  
STAGE_HANDLE sth;
static segment("L1_data_b")  
FUNDAMENT_DATA_ENTRY vfd;

/* ------------------------------------------------------------------------ */

void init_stage_handle (void) {

STAGE_HANDLE *S;
S = &sth;
S->V = &vst;

#if STAGE>=2
S->M = &mst;
#endif

#if STAGE==3
S->L = &lst;
#endif			
init_first_stage (S);

#if STAGE>=2
init_sec_stage (S);
#endif

#if STAGE==3
init_last_stage (S);
#endif	

}

/* ------------------------------------------------------------------------ */

void init_src (void) {

FUNDAMENT_DATA_ENTRY *F;
F = &vfd;
F->S = &sth;

F->half_band = 		HALFB;
F->up_stage = 		NUPST;
F->pivot_stage = 	PVTFL;
F->down_stage = 	NDWNS;
F->nstages = 		STAGE;
F->ninputs = 		NINPS;
F->noutputs = 		NOUTS;

src_init (F);

}

/* ------------------------------------------------------------------------ */

/*


Shell test program.. eventually I will use Fread and Fwrite to input/output ASCII files
(JWS)

*/
int i,j=0,count,file_status;  //global variables

int getInput(short *inBuf,int count);
int writeOutput(short *outBuf,int count);

int main()
{

//int i,j=0,count,file_status;

	/* initialize filter */

inFile = fopen("C:\\DSP\\sin_1khz_44khz.dat","rb");
outFile = fopen("C:\\DSP\\out_1khz_44to48.dat","wb");

init_stage_handle();
init_src();

count = getInput(x,NINPS);


while(count==NINPS)
{ 
	/* filter samples */ 
j=j+1;
#if STAGE==3
src_flt (x, y, DOFS3, &vfd);
#endif
 

#if STAGE==1 
src_flt (x, y, DOFS1, &vfd);
#endif


#if STAGE==2
src_flt (x, y, DOFS2, &vfd);
#endif


count = writeOutput(y,NOUTS);

count = getInput(x,NINPS);
}

fclose(inFile);
fclose(outFile);

}


int getInput(short *inBuf,int count)
{
	
	int wordsRead=0;

	wordsRead = fread(inBuf,sizeof(short),count,inFile);

	return wordsRead;

}

int writeOutput(short *outBuf,int count)
{
	int wordsRead=0;
	
	wordsRead = fwrite(outBuf,sizeof(short),count,outFile);
	
	return wordsRead;
	
}


 

⌨️ 快捷键说明

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