| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include "fourier.h"
- #include "ddcmath.h"
- #include "fft.h"
- #include "cmsis_os.h"
- #include "ImC/imc_extension.h"
- #define CHECKPOINTER(p) CheckPointer(p, #p)
- static void CheckPointer(void *p, char *name)
- {
- if (p == NULL)
- {
- // fprintf(stderr, "Error in fft_float(): %s == NULL\n", name);
- printf("Error in fft_float(): %s == NULL\n", name);
- exit(1);
- }
- }
- void vFFT()
- {
- unsigned MAXSIZE;
- unsigned MAXWAVES;
- unsigned i, j;
- int invfft = 0;
- MAXSIZE = 128;
- MAXWAVES = 4;
- // int IMC_REPEAT = 30;
- int IMC_REPEAT = imcBENCH_REPEAT_COUNT;
- // srand(1);
-
- float RealIn[MAXSIZE];
- float ImagIn[MAXSIZE];
- float RealOut[MAXSIZE];
- float ImagOut[MAXSIZE];
- float coeff[MAXWAVES];
- float amp[MAXWAVES];
- // IMC_UNROLL(1)
- for (int imc_repeat=0; imc_repeat < IMC_REPEAT; imc_repeat++) {
- /* Makes MAXWAVES waves of random amplitude and period */
- IMC_UNROLL(4)
- for (i = 0; i < MAXWAVES; i++)
- {
- // coeff[i] = rand() % 1000;
- // amp[i] = rand() % 1000;
- coeff[i] = 123;
- amp[i] = 456;
- // coeff[i] = i;
- // amp[i] = i+1;
- }
- IMC_UNROLL(4)
- for (i = 0; i < MAXSIZE; i++)
- {
- /* RealIn[i]=rand();*/
- RealIn[i] = 0;
- ImagIn[i] = 0;
- float sum = 0;
- IMC_UNROLL(4)
- for (j = 0; j < MAXWAVES; j++)
- {
- /* randomly select sin or cos */
- if (i % 2)
- {
- sum += coeff[j] * cos(amp[j] * i);
- // RealIn[i] += coeff[j] * cos(amp[j] * i);
- }
- else
- {
- // RealIn[i] += coeff[j] * sin(amp[j] * i);
- sum += coeff[j] * sin(amp[j] * i);
- }
- }
- RealIn[i] = sum;
- }
- /* regular*/
- {
- unsigned NumBits; /* Number of bits needed to store indices */
- unsigned i, j, k, n;
- unsigned BlockSize, BlockEnd;
- double angle_numerator = 2.0 * DDC_PI;
- double tr, ti; /* temp real, temp imaginary */
- unsigned NumSamples = MAXSIZE;
- int InverseTransform = invfft;
- if (!IsPowerOfTwo(NumSamples))
- {
- // fprintf(
- // stderr,
- // "Error in fft(): NumSamples=%u is not power of two\n",
- // NumSamples);
- printf(
- "Error in fft(): NumSamples=%u is not power of two\n",
- NumSamples);
- // exit(1);
- // return;
- }
- if (InverseTransform)
- angle_numerator = -angle_numerator;
- NumBits = NumberOfBitsNeeded(NumSamples);
- /*
- ** Do simultaneous data copy and bit-reversal ordering into outputs...
- */
- for (i = 0; i < NumSamples; i++)
- {
- j = ReverseBits(i, NumBits);
- RealOut[j] = RealIn[i];
- // ImagOut[j] = (ImagIn == NULL) ? 0.0 : ImagIn[i];
- ImagOut[j] = ImagIn[i];
- }
- /*
- ** Do the FFT itself...
- */
- BlockEnd = 1;
- for (BlockSize = 2; BlockSize <= NumSamples; BlockSize <<= 1)
- {
- double delta_angle = angle_numerator / (double)BlockSize;
- double sm2 = sin(-2 * delta_angle);
- double sm1 = sin(-delta_angle);
- double cm2 = cos(-2 * delta_angle);
- double cm1 = cos(-delta_angle);
- double w = 2 * cm1;
- double ar[3], ai[3];
- double temp;
- for (i = 0; i < NumSamples; i += BlockSize)
- {
- ar[2] = cm2;
- ar[1] = cm1;
- ai[2] = sm2;
- ai[1] = sm1;
- for (j = i, n = 0; n < BlockEnd; j++, n++)
- {
- ar[0] = w * ar[1] - ar[2];
- ar[2] = ar[1];
- ar[1] = ar[0];
- ai[0] = w * ai[1] - ai[2];
- ai[2] = ai[1];
- ai[1] = ai[0];
- k = j + BlockEnd;
- tr = ar[0] * RealOut[k] - ai[0] * ImagOut[k];
- ti = ar[0] * ImagOut[k] + ai[0] * RealOut[k];
- RealOut[k] = RealOut[j] - tr;
- ImagOut[k] = ImagOut[j] - ti;
- RealOut[j] += tr;
- ImagOut[j] += ti;
- }
- }
- BlockEnd = BlockSize;
- }
- /*
- ** Need to normalize if inverse transform...
- */
- if (InverseTransform)
- {
- double denom = (double)NumSamples;
- for (i = 0; i < NumSamples; i++)
- {
- RealOut[i] /= denom;
- ImagOut[i] /= denom;
- }
- }
- }
- } //imc_repeat
- /*
- portDISABLE_INTERRUPTS();
- printf("RealOut:\r\n");
- portENABLE_INTERRUPTS();
- for (i = 0; i < MAXSIZE; i++)
- printf("%f \t", RealOut[i]);
- printf("\r\n");
- printf("ImagOut:\r\n");
- for (i = 0; i < MAXSIZE; i++)
- printf("%f \t", ImagOut[i]);
- printf("\r\n");
- */
- float real_sum = 0;
- float imag_sum = 0;
- for (i = 0; i < MAXSIZE; i++) {
- real_sum += RealOut[i];
- imag_sum += ImagOut[i];
- }
- portDISABLE_INTERRUPTS();
- printf("(OUT) %d, %d\r\n", (int)(real_sum*1000000), (int)(imag_sum*1000000));
- portENABLE_INTERRUPTS();
- // printf("RealOut: ");
- // for (i = 0; i < 3; i++)
- // printf("%f\t", RealOut[i]);
- // printf("\r\n");
- // printf("ImagOut: ");
- // for (i = 0; i < 3; i++)
- // printf("%f\t", ImagOut[i]);
- // printf("\r\n");
- }
|