From: tuurbo46 on
Hi

Im currently in a bit of muddle. Im currently doing an assignment (in
c on TMS320C6713 DSK) and we have been told clearly that we cannot use
FFT and we must use Convolution.

At this point im reading lots of web sites (TI.Com) etc and i have
found a convolution.c example program. However when i read this
example they are implementing convolution whilst using FFT functions??

I have included the source code below, can somebody explain why they
have done this?



//FastConvo.c FIR filter implemented using overlap-add fast convolution

#include "DSK6713_AIC23.h"
Uint32 fs=DSK6713_AIC23_FREQ_8KHZ;

#include <math.h>
#include "coeffs.h" //time domain FIR coefficients
#define PI 3.14159265358979
#define PTS 256 //number of points for FFT
#define SQRT_PTS 16 //used in twiddle factor calc.
#define RADIX 2 //passed to TI FFT routines
#define DELTA (2*PI)/PTS
typedef struct Complex_tag {float real, imag;} COMPLEX ;
#pragma DATA_ALIGN(W, sizeof(COMPLEX))
#pragma DATA_ALIGN(samples, sizeof(COMPLEX))
#pragma DATA_ALIGN(h, sizeof(COMPLEX))
COMPLEX W[PTS/RADIX] ; //twiddle factor array
COMPLEX samples[PTS]; //processing buffer
COMPLEX h[PTS]; //FIR filter coefficients
short buffercount = 0; //buffer count for iobuffer samples
float iobuffer[PTS/2]; //primary input/output buffer
float overlap[PTS/2]; //intermediate result buffer
short i; //index variable
short flag = 0; //set to indicate iobuffer full
float a, b; //variables used in complex multiply
short NUMCOEFFS = sizeof(coeffs)/sizeof(float);
short iTwid[SQRT_PTS] ; //PTS/2 + 1 > sqrt(PTS)

interrupt void c_int11(void) //ISR
{
output_sample((short)(iobuffer[buffercount]));
iobuffer[buffercount++] = (float)((short)input_sample());
if (buffercount >= PTS/2) //for overlap-add method iobuffer
{ //is half size of FFT used
buffercount = 0;
flag = 1;
}
}

main()
{ //set up array of twiddle factors
digitrev_index(iTwid, PTS/RADIX, RADIX);
for(i = 0 ; i < PTS/RADIX ; i++)
{
W[i].real = cos(DELTA*i);
W[i].imag = sin(DELTA*i);
}
bitrev(W, iTwid, PTS/RADIX); //bit reverse order W

for (i = 0 ; i<PTS ; i++) //initialise PTS element
{ //of COMPLEX to hold real-valued
h[i].real = 0.0; //time domain FIR filter coefficients
h[i].imag = 0.0;
}
for (i = 0 ; i < NUMCOEFFS ; i++)
{ //read FIR filter coeffs
h[i].real = coeffs[i]; //NUMCOEFFS should be less than PTS/2
}
cfftr2_dit(h,W,PTS); //transform filter coeffs
comm_intr(); //initialise DSK, codec, McBSP

while(1) //frame processing infinite loop
{
while (flag == 0); //wait for iobuffer full
flag = 0;
for (i = 0 ; i<PTS/2 ; i++) //iobuffer into first half of
{ //samples buffer
samples[i].real = iobuffer[i];
iobuffer[i] = overlap[i]; //previously processed output
} //to iobuffer
for (i = 0 ; i<PTS/2 ; i++)
{ //second half of samples to overlap
overlap[i] = samples[i+PTS/2].real;
samples[i+PTS/2].real = 0.0;//zero-pad input from iobuffer
}
for (i=0 ; i<PTS ; i++)
samples[i].imag = 0.0; //init imag parts in samples buffer

cfftr2_dit(samples,W,PTS); //complex FFT function from TI

for (i=0 ; i<PTS ; i++) //frequency-domain representation
{ //complex multiply samples by h
a = samples[i].real;
b = samples[i].imag;
samples[i].real = h[i].real*a - h[i].imag*b;
samples[i].imag = h[i].real*b + h[i].imag*a;
}

icfftr2_dif(samples,W,PTS); //inverse FFT function from TI

for (i=0 ; i<PTS ; i++)
samples[i].real /= PTS;
for (i=0 ; i<PTS/2 ; i++) //add first half of samples
overlap[i] += samples[i].real; //to overlap
} //end of while(1)
} //end of main()

From: Bhaskar Thiagarajan on
<tuurbo46(a)yahoo.co.uk> wrote in message
news:1139239180.395187.271000(a)o13g2000cwo.googlegroups.com...
> Hi
>
> Im currently in a bit of muddle. Im currently doing an assignment (in
> c on TMS320C6713 DSK) and we have been told clearly that we cannot use
> FFT and we must use Convolution.
>
> At this point im reading lots of web sites (TI.Com) etc and i have
> found a convolution.c example program. However when i read this
> example they are implementing convolution whilst using FFT functions??

Just because your assignment has some constraints doesn't mean others need
to follow that too. This is a fast convolution technique that uses the FFT -
this isn't very uncommon.
Search for FIR example functions - that'll give you what you are looking for
(convolution without using FFT).

Cheers
Bhaskar

>
> I have included the source code below, can somebody explain why they
> have done this?
>
>
>
> //FastConvo.c FIR filter implemented using overlap-add fast convolution
>
> #include "DSK6713_AIC23.h"
> Uint32 fs=DSK6713_AIC23_FREQ_8KHZ;
>
> #include <math.h>
> #include "coeffs.h" //time domain FIR coefficients
> #define PI 3.14159265358979
> #define PTS 256 //number of points for FFT
> #define SQRT_PTS 16 //used in twiddle factor calc.
> #define RADIX 2 //passed to TI FFT routines
> #define DELTA (2*PI)/PTS
> typedef struct Complex_tag {float real, imag;} COMPLEX ;
> #pragma DATA_ALIGN(W, sizeof(COMPLEX))
> #pragma DATA_ALIGN(samples, sizeof(COMPLEX))
> #pragma DATA_ALIGN(h, sizeof(COMPLEX))
> COMPLEX W[PTS/RADIX] ; //twiddle factor array
> COMPLEX samples[PTS]; //processing buffer
> COMPLEX h[PTS]; //FIR filter coefficients
> short buffercount = 0; //buffer count for iobuffer samples
> float iobuffer[PTS/2]; //primary input/output buffer
> float overlap[PTS/2]; //intermediate result buffer
> short i; //index variable
> short flag = 0; //set to indicate iobuffer full
> float a, b; //variables used in complex multiply
> short NUMCOEFFS = sizeof(coeffs)/sizeof(float);
> short iTwid[SQRT_PTS] ; //PTS/2 + 1 > sqrt(PTS)
>
> interrupt void c_int11(void) //ISR
> {
> output_sample((short)(iobuffer[buffercount]));
> iobuffer[buffercount++] = (float)((short)input_sample());
> if (buffercount >= PTS/2) //for overlap-add method iobuffer
> { //is half size of FFT used
> buffercount = 0;
> flag = 1;
> }
> }
>
> main()
> { //set up array of twiddle factors
> digitrev_index(iTwid, PTS/RADIX, RADIX);
> for(i = 0 ; i < PTS/RADIX ; i++)
> {
> W[i].real = cos(DELTA*i);
> W[i].imag = sin(DELTA*i);
> }
> bitrev(W, iTwid, PTS/RADIX); //bit reverse order W
>
> for (i = 0 ; i<PTS ; i++) //initialise PTS element
> { //of COMPLEX to hold real-valued
> h[i].real = 0.0; //time domain FIR filter coefficients
> h[i].imag = 0.0;
> }
> for (i = 0 ; i < NUMCOEFFS ; i++)
> { //read FIR filter coeffs
> h[i].real = coeffs[i]; //NUMCOEFFS should be less than PTS/2
> }
> cfftr2_dit(h,W,PTS); //transform filter coeffs
> comm_intr(); //initialise DSK, codec, McBSP
>
> while(1) //frame processing infinite loop
> {
> while (flag == 0); //wait for iobuffer full
> flag = 0;
> for (i = 0 ; i<PTS/2 ; i++) //iobuffer into first half of
> { //samples buffer
> samples[i].real = iobuffer[i];
> iobuffer[i] = overlap[i]; //previously processed output
> } //to iobuffer
> for (i = 0 ; i<PTS/2 ; i++)
> { //second half of samples to overlap
> overlap[i] = samples[i+PTS/2].real;
> samples[i+PTS/2].real = 0.0;//zero-pad input from iobuffer
> }
> for (i=0 ; i<PTS ; i++)
> samples[i].imag = 0.0; //init imag parts in samples buffer
>
> cfftr2_dit(samples,W,PTS); //complex FFT function from TI
>
> for (i=0 ; i<PTS ; i++) //frequency-domain representation
> { //complex multiply samples by h
> a = samples[i].real;
> b = samples[i].imag;
> samples[i].real = h[i].real*a - h[i].imag*b;
> samples[i].imag = h[i].real*b + h[i].imag*a;
> }
>
> icfftr2_dif(samples,W,PTS); //inverse FFT function from TI
>
> for (i=0 ; i<PTS ; i++)
> samples[i].real /= PTS;
> for (i=0 ; i<PTS/2 ; i++) //add first half of samples
> overlap[i] += samples[i].real; //to overlap
> } //end of while(1)
> } //end of main()
>


From: Jerry Avins on
Bhaskar Thiagarajan wrote:
> <tuurbo46(a)yahoo.co.uk> wrote in message
> news:1139239180.395187.271000(a)o13g2000cwo.googlegroups.com...
>
>>Hi
>>
>>Im currently in a bit of muddle. Im currently doing an assignment (in
>>c on TMS320C6713 DSK) and we have been told clearly that we cannot use
>>FFT and we must use Convolution.
>>
>>At this point im reading lots of web sites (TI.Com) etc and i have
>>found a convolution.c example program. However when i read this
>>example they are implementing convolution whilst using FFT functions??
>
>
> Just because your assignment has some constraints doesn't mean others need
> to follow that too. This is a fast convolution technique that uses the FFT -
> this isn't very uncommon.
> Search for FIR example functions - that'll give you what you are looking for
> (convolution without using FFT).
>
> Cheers
> Bhaskar

...

Turbo46,

I'm here to elaborate and to scold. I don't know who should be scolded,
I presume it is the instructor. By the time one gets an assignment like
yours, one should know that convolution in the time domain has the same
effect as multiplication in the frequency domain (and vice versa). This
means that it is possible to convolve in the time domain by using FFT to
convert to frequency, multiplying, and then using IFFT co convert back
to time. It may be surprising, but this procedure is faster than direct
convolution for large enough sample sets.

What books do you have access to? At your apparent level, I recommend
Lyons. Understanding Digital Signal Processing
http://www.amazon.com/gp/product/0131089897/sr=1-1/qid=1139254956/ref=pd_bbs_1/103-8646755-9878217?%5Fencoding=UTF8
Another good book, Smith, The Scientist and Engineer's Guide to Digital
Signal Processing is available on line chapter by chapter in PDF at
http://www.dspguide.com/. Chapter 16 deals with direct convolution,
among other topics.

Just as it is hard to manage a company whose business one doesn't
understand, it is hard to write a good program to do something one
doesn't understand.

Jerry
--
Engineering is the art of making what you want from things you can get.
???????????????????????????????????????????????????????????????????????
From: James Van Buskirk on
"Jerry Avins" <jya(a)ieee.org> wrote in message
news:nYGdnaaze4b5NHreRVn-ow(a)rcn.net...

> I'm here to elaborate and to scold. I don't know who should be scolded,
> I presume it is the instructor. By the time one gets an assignment like
> yours, one should know that convolution in the time domain has the same
> effect as multiplication in the frequency domain (and vice versa). This
> means that it is possible to convolve in the time domain by using FFT to
> convert to frequency, multiplying, and then using IFFT co convert back
> to time. It may be surprising, but this procedure is faster than direct
> convolution for large enough sample sets.

There is another technique for computing a 2**n-point circular
convolution that doesn't compute the 2**n-point DFT of the
inputs and the inverse 2**n-point DFT to get the outputs.
Perhaps that is what your professor was referring to. You
can get a code generator at

http://home.comcast.net/~kmbtib/conv2c.f90 .

Since you probably don't have a Fortran compiler, you can
get one quite easily at http://www.g95.org . The generated
code, while in Fortran, can be converted to C by putting
a semicolon at the end of each line and a few other minor
changes.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Jerry Avins on
James Van Buskirk wrote:

...

> There is another technique for computing a 2**n-point circular
> convolution that doesn't compute the 2**n-point DFT of the
> inputs and the inverse 2**n-point DFT to get the outputs.
> Perhaps that is what your professor was referring to. You
> can get a code generator at
>
> http://home.comcast.net/~kmbtib/conv2c.f90 .

That's a lot of code to read and understand. Is there a short
explanation of how fast convolution is done without FFT etc.?

Jerry
--
Engineering is the art of making what you want from things you can get.
???????????????????????????????????????????????????????????????????????
 |  Next  |  Last
Pages: 1 2 3
Prev: dspGuru is alive and well!
Next: Software PLL (SPLL)