This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C64x+ DSP Library (DSPLIB) v2.10 -- FFT and IFFT scaling issues

Other Parts Discussed in Thread: SPRC265

I once again raise a question regarding DSPLIB's FFT / IFFT scaling, as this topic is not well-covered in the API documentation ( http://focus.ti.com/lit/ug/sprueb8b/sprueb8b.pdf ).

I'm using
*TMS320TCI6482
*C64x+ DSP Library (DSPLIB) v2.10 .... ( http://focus.ti.com/docs/toolsw/folders/print/sprc265.html )
*C6000 Code Generation Tools (CGT) v7.0.1 .... ( https://www-a.ti.com/downloads/sds_support/TICodegenerationTools/download.htm )
*everything in little Endian

I compiled mentioned DSPLIB with mentioned CGT. I'm sampling signals from a microphone. The codec (AIC23B) provides samples at 48 kHz.

First, I generate twiddle factors for both my 256-FFT and my 256-IFFT
gen_twiddle_fft16x16(w, 256);
gen_twiddle_ifft16x16(iw, 256);
(sidenote 1: oddly, the twiddle functions are not part of the compiled library distribution, but are only available in source code)
(sidenote 2: oddly, the API documentation makes the impression that it's okay to use the same twiddle factors for both the FFT and IFFT, which is imho wrong)

I collect 256 samples of size short / Int16 / Q15 (everything is the same anyways) in an array, x1[512]. I write the samples to every even memory position (real parts). The odd memory positions are zero (imaginary parts).

I then take these 256 samples, pass them through one of DSPLIB's FFT function:
DSP_fft16x16(w, 256, x1, y1);

I then take the transformed samples and put them in the IFFT:
DSP_ifft16x16(iw, 256, y1, y2);

(sidenote 3: the FFT / IFFT functions work destructively on the input arrays. This is not documented in the API documentation)

Now I play back the real part of the y2 array on my headphones. When I whisper into the microphone, I can hear the same coming out of my headphone as what I'm whispering into the microphone. This is good.... When I speak with normal loudness, I only get distorted signals. This is bad.

I guess the distortion comes from overflow during the FFT and IFFT phases whenever these transforms have to work on signals which are too strong/loud/have to much energy. I tried different scalings for both y1 and y2 (dividing by 4... 8... 64... 256... etc.), but I always get distortions when speaking with normal loudness.

So the question is: How do I scale correctly? Basically all I want is speak in the microphone at any loudness and hear the same in my headphones. This should be possible with 256-FFT and 256-IFFT at 16 bits, right? Notice that the dynamic range of my samples is important (it's voice).

Basically, the problem with DSPLIB is, that both
*the API does not abstract/hide FFT domain knowledge, expecting the user to be an FFT implementation expert and knowing about scaling, twiddle factors, overflow and such, and
*the API documentation does not explain the usage of the API well.

I'm looking forward for your suggestions.

Cheers,
Jerry

  • See the wiki note: http://processors.wiki.ti.com/index.php?title=FFT_Implementation_With_No_Data_Scaling
    may help understand how the scaling is applied in FFT kernels and how it can be removed or adjusted

    Regards.

  • I am having the same issues, what a waste of time this code from TI. Do you have plain simple sample code to do both FFT and iFFT on 32 bits inputs THAT WROKS (very important fact)?

    thanks

  • Ali, sorry for your trouble. But what is your issue? Yes, we do have 32bit FFT implementation that works as part of the DSPLIB. There is plain C implementation along with optimized C implementation. There is also usage example C:\c64plus-dsplib_2_02_00_00\example\fft_example

    Can you please be more specific on what you issue is?

    Cheers,
    Gagan 

  • I also have a question regarding how to feed input to DSP_fft32x32

    I'm reading the example download from http://processors.wiki.ti.com/index.php/FFT/IFFT:_2D_Implementation

    The input of that example is an image (0~255), each pixel is scaled as (pixel[i]/255)*(2147483648/N).

    Why it need to normalize input to pixel[i]/255 and then convert to integer (by *2147483648), and then scale down (by /N)?

    Can I directly pass pixel[i] as input if I'm doing 512x512 fft? Since image pixel only has 8 bit, and 512 fft will shift 9 bit, it won't have overflow in this case. Am I correct?

     

     

     

  • SA

    When you comapre the ifft input with the fft output (fft output/ifft input)should be a constant for all elemnents,you should use a prescaling before the ifft & a prescaling before fft to do this purpose.

    To get these 2 prescaling factors u can get them by try and error .

     

  • HI Gagan,

     

    I read the wiki link you have given. My question is do you have this fix for big endian libraries?

    Thanks and Regards,

    Suresh

  • Dear Gagan,

    many thanks for the article. It’s really a very clear and useful description in contrast with the sprueb8. Nevertheless I have some additional questions:

    1.       1. You have analyzed the behavior of in series implemented functions DSP_fft16x16() and DSP_ifft16x16() for the fft/iff size 256. These have three internal Radix-4 stages and another external one. Scaling for the internal loops will produce the same transfer coefficients for every of fft and ifft functions, namely 2. In this way the total transfer coefficient for in series fft and ifft is equal to 4. I have tested the behavior on the C6455 DSK and can also confirm this. But for the external stage Radix-2 (i.e. fft/iff size 32, 128, 512, 2048 etc) the measured total transfer coefficient for in series fft and ifft is equal to 2.
    How the individual transfer coefficients will be distributed between fft/ifft functions – 1 and 2, 2 and 1 or sqrt(2) and sqrt(2)?

    2.       2. Whether the implemented on the internal stages scaling by 2 shall guarantee that the output signal will be absolutely overfloating free? If no, then how the needed scaling should be calculated to avoid overfloating totally?

    2.       Regards