DSPRelated.com
Forums

FIR timing problem?

Started by julianoys February 23, 2005
Hello Everybody!

It's my first post on this forum, can anyone help me?
I'm newbie on DSP and I'm using TMS320C5402 DSK Board... I've used the
codec.c digital loopback example to implement my own FIR filter as someone
told already in a post from this forum.
The problem it's that I think it's not working as it should...
I'm going to attach the code for you guys to take a look...

After the input sample is stored at "data" variable, I loop over the
coefficients from matlab (multiplied by 32768) and convolved with the
input samples. Afterwards the convolution is divided by 32768 to give me
the real result (tried to <<32769 but didn't seem to work) and output that
value to the codec... APARENTLY it filtered the sound... can't really
because I don't have an oscilloscope or a function generator nearby to
observe the shape of the waves. I say that because if I change the code
and throw the input sample directly to the output, but leaving the
filtering process (loops for convolution) unaltered, It should output the
sound with no changes... but that doesn't happen, the sound gets a little
distorced. (Can test by commenting the convolution loops)
I believe that there's a timing problem on the code, but I don't know for
sure, cause I've already read something about TMS320C5402 being used on
video, and some heavy jobs... can't it support a simple FIR filter???

I've got also DSPLib and read SPRU518D on how to use it... but honestly...
did anyone understant it? Example on Fir directory didn't help too much...
actually didn't even work!?

I'm studying Assembly in an attempt to optimize code, but it's very
confuse... it's my first time to deal with Assembly... so imagine...

If someone knows what's happening, could please help me?
Alse if anyone has a WORKING Fir code for the TMS320C5402 could send a
copy to me, please? Needed this working as soon as possible.
Thanks a LOT for the attention...

Good Day!
---------------

FIR CODE:

/*****************************************************************************/
/* Codec.c                                                                
  */
/*                                                                        
  */
/* Digital Loopback example                                               
  */
/*                                                                        
  */
/*****************************************************************************/

#include <type.h>
#include <board.h>
#include <codec.h>
#include <mcbsp54.h>

/*****************************************************************************/
/* Function Prototypes                                                    
  */
/*****************************************************************************/

/* This delay routine does not conflict with DSP/BIOS.  It is used in this
 */
/* example rather than brd_delay_msec which causes DSP/BIOS conflicts just
 */
/* because of this.  If you are not using DSP/BIOS, you can change the
code */
/* to use brd_delay_msec.                                                 
 */

void delay(s16 period);  
void move(int);

/*****************************************************************************/
/* Global Variables                                                       
  */
/*****************************************************************************/

HANDLE hHandset;
s16 data, out, sinal[100];
long conv;

/*
High-Pass Filter - Kaiser FIR
fs = 16000
fc = [1000 1500]
mags = [0 1]
dev = [0.1 0.1]
[n,wn,beta,ftype]=kaiserord(fc, mags, dev, fs)
[b]=fir1(n,wn,ftype,kaiser(n+1,beta))
*/

s16 coef[29] = {
		-421,	-80,	338,	746,	1041,
		1128,	938,	440,	-345,	-1346,
		-2450,	-3519,	-4411,	-5001,	28120,
		-5001,	-4411,	-3519,	-2450,	-1346,
		-345,	440,	938,	1128,	1041,
		746,	338,	-80,	-421};         

/*
Low-Pass Filter - Kaiser FIR
fs = 16000
fc = [1000 1500]
mags = [1 0]
dev = [0.1 0.1]
[n,wn,beta,ftype]=kaiserord(fc, mags, dev, fs)
[b]=fir1(n,wn,ftype,kaiser(n+1,beta))

s16 coef[28] = {		
		284,	-133,	-588,	-978,	-1194,
		-1146,	-779,	-86,	883,	2028,
		3210,	4278,	5086,	5520,	5520,
		5086,	4278,	3210,	2028,	883,
		-86,	-779,	-1146,	-1194,	-978,
		-588,	-133,	284};		
*/

/*
Test-Mode for Loopback
s16 coef[28] = {		
		32767,	0,	0,	0,	0,
		0,	0,	0,	0,	0,
		0,	0,	0,	0,	0,
		0,	0,	0,	0,	0,
		0,	0,	0,	0,	0,
		0,	0,	0};		
*/

int i, nsamples = 29; /* nsamples must be equal to number os coefficients
of filter */

/*****************************************************************************/
/* MAIN                                                                   
  */
/*****************************************************************************/

void main()
{
    s16 cnt=2;

    if (brd_init(100))   
        return;

	/* blink the leds a couple times */
	while ( cnt-- )
	{
		brd_led_toggle(BRD_LED0);
		/* brd_delay_msec(1000); */
		delay(1000);
		brd_led_toggle(BRD_LED1);
		/* brd_delay_msec(1000); */
		delay(1000);
		brd_led_toggle(BRD_LED2);
		/* brd_delay_msec(1000); */
		delay(1000);
	}


    /* Open Handset Codec */
    hHandset = codec_open(HANDSET_CODEC);               /* Acquire handle
to codec */

    /* Set codec parameters */
    codec_dac_mode(hHandset, CODEC_DAC_15BIT);          /* DAC in 15-bit
mode */
    codec_adc_mode(hHandset, CODEC_ADC_15BIT);          /* ADC in 15-bit
mode */
    codec_ain_gain(hHandset, CODEC_AIN_6dB);            /* 6dB gain on
analog input to ADC */
    codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB);    /* -6dB gain on
analog output from DAC */
    codec_sample_rate(hHandset,SR_16000);               /* 16KHz sampling
rate */

    /* Polling and digital loopback */
    while (1)
    {
       /* Wait for sample from handset */
       while (!MCBSP_RRDY(HANDSET_CODEC)) {};

       /* Read sample from and write back to handset codec */
       data = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC);
        
       /* ********** IN&#4294967295;CIO DO FILTRO *********** */
        
    	sinal[nsamples-1] = data; 
    	
    	conv = 0;
    	
    	for (i = 0; i < nsamples; i++)
    		conv += sinal[nsamples-1-i] * coef[i];
    	
		move(nsamples); 
		
		out = conv/32768;
	    
	   /* *********** FIM DO FILTRO *********** */
       
       *(volatile u16*)DXR1_ADDR(HANDSET_CODEC) = out;
    }
}


void delay(s16 period)
{
    int i, j;
    
    for(i = 0; i < period; i++)
    {
        for(j = 0; j < period >> 1; j++);
    }
}        
      
void move (int n)
{
int cont;
for (cont = 1; cont < n; cont ++)
	sinal[cont - 1] = sinal[cont];
}                                                                     



		
This message was sent using the Comp.DSP web interface on
www.DSPRelated.com
I am unfamiliar with TI stuff, but if you are getting distortion while
attempting to simulate a piece of wire, it is easy to do if you transfer
variables between incorrectly cast or defined storage types/sizes (ints,
fracs, floats etc.).

By the way it seems like a lot of code.

Jim Adamthwaite


I see a few things right away that you need to address:

(1) Read the 54x compiler guide (spru103d) and learn how to use the 54x
compiler intrinsics to get proper behavior when doing multiplies and
multiply and accumulates.  Your main for loop should be using the _smac( )
instrinsic to get the proper Q value of the multiply result. (Are you
familiar with Q math rules?)

(2) I don't see where your input buffer is being updated, I see the last
element updated,but not where it is being shifted through the buffer.

(3) Don't use a linear buffer for your data, use a circular buffer.

(4) You will need to learn how to either use the DSP LIB or write ASM.  I
would never expect straight C code give the proper results OR be fast
enough.

Good luck and have fun.

-Shawn


"julianoys" <julianoys@uol.com.br> wrote in message
news:-5qdnevjELTuf4HfRVn-2Q@giganews.com...
> Hello Everybody! > > It's my first post on this forum, can anyone help me? > I'm newbie on DSP and I'm using TMS320C5402 DSK Board... I've used the > codec.c digital loopback example to implement my own FIR filter as someone > told already in a post from this forum. > The problem it's that I think it's not working as it should... > I'm going to attach the code for you guys to take a look... > > After the input sample is stored at "data" variable, I loop over the > coefficients from matlab (multiplied by 32768) and convolved with the > input samples. Afterwards the convolution is divided by 32768 to give me > the real result (tried to <<32769 but didn't seem to work) and output that > value to the codec... APARENTLY it filtered the sound... can't really > because I don't have an oscilloscope or a function generator nearby to > observe the shape of the waves. I say that because if I change the code > and throw the input sample directly to the output, but leaving the > filtering process (loops for convolution) unaltered, It should output the > sound with no changes... but that doesn't happen, the sound gets a little > distorced. (Can test by commenting the convolution loops) > I believe that there's a timing problem on the code, but I don't know for > sure, cause I've already read something about TMS320C5402 being used on > video, and some heavy jobs... can't it support a simple FIR filter??? > > I've got also DSPLib and read SPRU518D on how to use it... but honestly... > did anyone understant it? Example on Fir directory didn't help too much... > actually didn't even work!? > > I'm studying Assembly in an attempt to optimize code, but it's very > confuse... it's my first time to deal with Assembly... so imagine... > > If someone knows what's happening, could please help me? > Alse if anyone has a WORKING Fir code for the TMS320C5402 could send a > copy to me, please? Needed this working as soon as possible. > Thanks a LOT for the attention... > > Good Day! > --------------- > > FIR CODE: > >
/*************************************************************************** **/
> /* Codec.c > */ > /* > */ > /* Digital Loopback example > */ > /* > */ >
/*************************************************************************** **/
> > #include <type.h> > #include <board.h> > #include <codec.h> > #include <mcbsp54.h> > >
/*************************************************************************** **/
> /* Function Prototypes > */ >
/*************************************************************************** **/
> > /* This delay routine does not conflict with DSP/BIOS. It is used in this > */ > /* example rather than brd_delay_msec which causes DSP/BIOS conflicts just > */ > /* because of this. If you are not using DSP/BIOS, you can change the > code */ > /* to use brd_delay_msec. > */ > > void delay(s16 period); > void move(int); > >
/*************************************************************************** **/
> /* Global Variables > */ >
/*************************************************************************** **/
> > HANDLE hHandset; > s16 data, out, sinal[100]; > long conv; > > /* > High-Pass Filter - Kaiser FIR > fs = 16000 > fc = [1000 1500] > mags = [0 1] > dev = [0.1 0.1] > [n,wn,beta,ftype]=kaiserord(fc, mags, dev, fs) > [b]=fir1(n,wn,ftype,kaiser(n+1,beta)) > */ > > s16 coef[29] = { > -421, -80, 338, 746, 1041, > 1128, 938, 440, -345, -1346, > -2450, -3519, -4411, -5001, 28120, > -5001, -4411, -3519, -2450, -1346, > -345, 440, 938, 1128, 1041, > 746, 338, -80, -421}; > > /* > Low-Pass Filter - Kaiser FIR > fs = 16000 > fc = [1000 1500] > mags = [1 0] > dev = [0.1 0.1] > [n,wn,beta,ftype]=kaiserord(fc, mags, dev, fs) > [b]=fir1(n,wn,ftype,kaiser(n+1,beta)) > > s16 coef[28] = { > 284, -133, -588, -978, -1194, > -1146, -779, -86, 883, 2028, > 3210, 4278, 5086, 5520, 5520, > 5086, 4278, 3210, 2028, 883, > -86, -779, -1146, -1194, -978, > -588, -133, 284}; > */ > > /* > Test-Mode for Loopback > s16 coef[28] = { > 32767, 0, 0, 0, 0, > 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, > 0, 0, 0}; > */ > > int i, nsamples = 29; /* nsamples must be equal to number os coefficients > of filter */ > >
/*************************************************************************** **/
> /* MAIN > */ >
/*************************************************************************** **/
> > void main() > { > s16 cnt=2; > > if (brd_init(100)) > return; > > /* blink the leds a couple times */ > while ( cnt-- ) > { > brd_led_toggle(BRD_LED0); > /* brd_delay_msec(1000); */ > delay(1000); > brd_led_toggle(BRD_LED1); > /* brd_delay_msec(1000); */ > delay(1000); > brd_led_toggle(BRD_LED2); > /* brd_delay_msec(1000); */ > delay(1000); > } > > > /* Open Handset Codec */ > hHandset = codec_open(HANDSET_CODEC); /* Acquire handle > to codec */ > > /* Set codec parameters */ > codec_dac_mode(hHandset, CODEC_DAC_15BIT); /* DAC in 15-bit > mode */ > codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC in 15-bit > mode */ > codec_ain_gain(hHandset, CODEC_AIN_6dB); /* 6dB gain on > analog input to ADC */ > codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB); /* -6dB gain on > analog output from DAC */ > codec_sample_rate(hHandset,SR_16000); /* 16KHz sampling > rate */ > > /* Polling and digital loopback */ > while (1) > { > /* Wait for sample from handset */ > while (!MCBSP_RRDY(HANDSET_CODEC)) {}; > > /* Read sample from and write back to handset codec */ > data = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC); > > /* ********** IN&#4294967295;CIO DO FILTRO *********** */ > > sinal[nsamples-1] = data; > > conv = 0; > > for (i = 0; i < nsamples; i++) > conv += sinal[nsamples-1-i] * coef[i]; > > move(nsamples); > > out = conv/32768; > > /* *********** FIM DO FILTRO *********** */ > > *(volatile u16*)DXR1_ADDR(HANDSET_CODEC) = out; > } > } > > > void delay(s16 period) > { > int i, j; > > for(i = 0; i < period; i++) > { > for(j = 0; j < period >> 1; j++); > } > } > > void move (int n) > { > int cont; > for (cont = 1; cont < n; cont ++) > sinal[cont - 1] = sinal[cont]; > } > > > > > This message was sent using the Comp.DSP web interface on > www.DSPRelated.com