Hello:

Posting this here as it seems germane to the forum and the version on Q&A forum not receiving response from XMOS.

The portion of the dsp_vector library that treats complex arithmetic requires real and imaginary parts in separate vectors. Yet the same library's FFT provides real and imaginary parts as elements of a structure, making the two portions, in a sense, incompatible. For instance, if I've read it correctly, a response to a related question (viewtopic.php?f=47&t=5199&p=26517&hilit=dsp_vector#p26517) suggests that users write their own routines for the dsp_vector library functions for this very reason.

I imagine almost all complex DSP is done on the results of FFTs, so am surprised these two libraries are not compatible.

Am I missing something? Is there an easy way to use these two libraries together? If not, any plans, XMOS, to make this possible?

Thanks,

Bill

## dsp_vector library inconsistency

I am looking at the lib_dsp.pdf version 3.0.0.

An example of the functions I would like to call is application of dsp_vector_mulv_complex() to the output of several dsp_fft_split_spectrum() calls. The latter works with variable type dsp_complex_t, whilst the former works with int32_t variable types. I copied below the prototypes from lib_dsp.pdf.

Please note that I understand at least one, albeit inefficient, way to make these and other lib_dsp functions work together (e.g., copying the dsp_complex_t real and imaginary parts to separate int32_t variables). I also know how to code up the complex multiply without using the library function (and thus avoiding the copying).

What I am asking is if there are any plans to re-write these, or add new, functions to be called with the same variable types, or if there is some "trick" I am missing that avoids inefficiencies like the copying I refer to. (I am assuming that a re-write or add, or "trick", would be more efficient than my xc-level code for the complex multiply.)

Note, also, it would be nice to have a library version of a dot product for complex vectors.

thanks,

Bill

dsp_fft_split_spectrum(dsp_complex_t pts[], const uint32_t N)

dsp_vector_mulv_complex(const int32_t input_vector_X_re[],

const int32_t input_vector_X_im[],

const int32_t input_vector_Y_re[],

const int32_t input_vector_Y_im[],

int32_t result_vector_R_re[],

int32_t result_vector_R_im[],

const int32_t vector_length,

const int32_t q_format)

In your case if you would like to use dsp_vector_mulv_complex() then I would recommend writing a type for deinterleave and interleave function. An array of dsp_complex_t is such that each real value is at every other word aligned position, as are the imaginary values.

You could use a reinterpret cast to make this easy, i.e.

Code: Select all

`int32_t re[L/2], im[L/2];`

for(unsigned i=0; i<L; i+=2){

re[i/2] = (complex, int32_t[])[i];

im[i/2] = (complex, int32_t[])[i+1];

}

I hope that helps.

I've used vectorLength rather than the length of the interleaved array.

In general the overhead off de-interleaving after the FFT is better than doing vector processing of interleaved I and Q.

J

Code: Select all

`void interleave (const int re[],`

const int im[],

dsp_complex_t complex[],

const unsigned vectorLength)

{

for (unsigned i=0; i<vectorLength; i++) {

(complex, int32_t[])[2*i] = re[i];

(complex, int32_t[])[2*i+1] = im[i];

}

}

void deinterleave (const dsp_complex_t complex[],

int re[],

int im[],

const unsigned vectorLength)

{

for (unsigned i=0; i<vectorLength; i++) {

re[i] = (complex, int32_t[])[2*i];

im[i] = (complex, int32_t[])[2*i+1];

}

}

cheers,

Bill

Thanks for the code help, too. I am unfamiliar with that casting method.

Is "re[i] = (complex, int32_t[])[2*i];" equivalent to "re[i] = complex[i].re;" ?

If not, how do they differ?

Thanks,

Bill

### Who is online

Users browsing this forum: No registered users and 22 guests