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.

LCDK Inexplicable #1.QNAN problem in Phase Vocoder implementation

Other Parts Discussed in Thread: TEST2

I'm a student at UCLA working on a DSP project for my design course. I'm running into an inexplicable problem

I am trying to make a phase vocoder on an LCDK-OMAP-L138 in CCSv5, but it is failing in an inexplicable way. When the global MODE variable is set to 1, we begin recording. After recording, we process in batch. To process, we take in a frame of data, in this case 1024 sample points and perform an FFT. We process this frame in the frequency domain by manipulating the phase. We then do an IFFT and perform the standard overlap-add operation to reconstruct our signal.

When we try to do pitch shift processing, (PITCH_SHIFT = 1), we can process this the first frame fine. When we perform the IFFT on the second frame and all subsequent frames afterwards, our operation returns an array of 1.#QNAN. I have no explanation for why our floating point operations are failing us. I can pinpoint no place in the code where we do division by zero or any operation that would return an invalid floating point.

The inexplicable part is that sometimes, our processing works fine and we have a completely valid array of numbers produced by the IFFT. We capture these numbers in a test array called TEST2[][]. Changing nothing in our code, it sometimes works and sometimes doesn't and I have no explanation. When we change modes to ROBOT (ROBOT = 1, PITCH_SHIFT=0) our processing works. When do perform time stretching, (ROBOT=0, PITCH_SHIFT=0) our processing works all the time. ONLY in pitchshift mode do we have this problem. Most of the time we get invalid floating points starting from frame 2. On different builds of the same exact code we get valid values. 

Can you guys run my project and try to figure out whats wrong?

The bulk of the project is located in vocoder+.c

I've attached the project and the GUI i used below. The GUI is very simple, it just changes some global values from 1 to 0  and vice versa. 

By default, MODE is set to 0, PITCH_SHIFT is 1, ROBOT is 0, and MODER is 1. 

MODE=1 begins recording after 3 seconds. The LEDs will light up one at a time to signal this

MODE=2 plays back our recording. If MODER is 1, it will play back our processed recording. It MODER is 0, it will play back our original recording

Vocoder+Project.zipVocoder+GUI.zip 

  • Hello Jason,

    Many floating point operations can return a NAN.

    Take a look a this: stackoverflow.com/.../1-qnan-error-c.

    Maybe you could a conditional break point in your code to help you track down where the NAN is originating from.

    Also, the project you attached doesn't contain any code.

    Stephen
  • My apologies on the attachments, there are two of them but they appear to have been put side by side on the same line. The project is attached at the bottom of the post, and the link to click is "Vocoder+Project.zip"
    The code for the majority of the project lies in "vocoder+.c", while the code for the fft lies in "fft.h"

    I understand that many floating point operations can return a NAN, but the weird thing in this case is that with the first frame in the first run through the loop, I always get a a valid array after the IFFT. Then when we go through the loop again with the second frame and all subsequent frames afterwards, with an array of similar numbers, the IFFT operation returns an array of NAN.

    The even weirder thing is that if I'm lucky, I can build the same exact code without changing anything and the operation will work all the time (for PITCH_SHIFT mode, the other two modes, ROBOT, and time stretching work fine all the time). Then when I rebuild/rerun the code after restarting the LCDK and CCS, it will break again.
  • Hello Jason,

    Just taking a quick look at your code I found the following issue (BATCH_PROCESSED array size is only NSAMPLES):

        for (i = 0; i < 2 * NSAMPLES; ++i)
        {	//initialize processing array to 0
            BATCH_PROCESSED[i] = 0;
        }

  • There's also an issue with this piece of code (i.e. You should use NUM_FRAMES instead of FRAMESIZE)

    :

        for (i = 0; i < FRAMESIZE; i++)
        {
            for (j = 0; j < FFTSIZE; j++)
            {
                TEST[i][j].real = 0;
                TEST[i][j].imag = 0;
                TEST2[i][j].real = 0;
                TEST2[i][j].imag = 0;
                TEST3[i][j].real = 0;
                TEST3[i][j].imag = 0;
            }
        }

  • Did my post solve your problem? If so, please click verify.