add temp buffer allocation and scaling by 2 for rfft
authorYang Zhang <yang.zhang@arm.com>
Mon, 30 Jun 2014 07:45:47 +0000 (15:45 +0800)
committerYang Zhang <yang.zhang@arm.com>
Tue, 1 Jul 2014 03:27:03 +0000 (11:27 +0800)
 - add temp buffer allocation in init function
 - add scaling by 2 for C, NEON assembly and intrinsic version

Change-Id: I7e46f327f43664e06700089f4d38f0d868d44f3e

12 files changed:
modules/dsp/NE10_fft_float32.c
modules/dsp/NE10_fft_float32.neon.c
modules/dsp/NE10_fft_float32.neonintrinsic.c
modules/dsp/NE10_fft_int16.c
modules/dsp/NE10_fft_int16.neon.c
modules/dsp/NE10_fft_int16.neonintrinsic.c
modules/dsp/NE10_fft_int32.c
modules/dsp/NE10_fft_int32.neon.c
modules/dsp/NE10_fft_int32.neonintrinsic.c
modules/dsp/test/test_suite_fft_float32.c
modules/dsp/test/test_suite_fft_int16.c
modules/dsp/test/test_suite_fft_int32.c

index d8580cc..011f1e1 100644 (file)
@@ -931,8 +931,8 @@ static void ne10_fft_split_c2r_1d_float32 (ne10_fft_cpx_float32_t *dst,
     ne10_fft_cpx_float32_t fk, fnkc, fek, fok, tmp;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) * 0.5f;
+    dst[0].i = (src[0].r - src[ncfft].r) * 0.5f;
 
     for (k = 1; k <= ncfft / 2; k++)
     {
@@ -949,11 +949,11 @@ static void ne10_fft_split_c2r_1d_float32 (ne10_fft_cpx_float32_t *dst,
         fok.r = tmp.r * twiddles[k - 1].r + tmp.i * twiddles[k - 1].i;
         fok.i = tmp.i * twiddles[k - 1].r - tmp.r * twiddles[k - 1].i;
 
-        dst[k].r = fek.r + fok.r;
-        dst[k].i = fek.i + fok.i;
+        dst[k].r = (fek.r + fok.r) * 0.5f;
+        dst[k].i = (fek.i + fok.i) * 0.5f;
 
-        dst[ncfft - k].r = fek.r - fok.r;
-        dst[ncfft - k].i = fok.i - fek.i;
+        dst[ncfft - k].r = (fek.r - fok.r) * 0.5f;
+        dst[ncfft - k].i = (fok.i - fek.i) * 0.5f;
     }
 }
 
@@ -995,11 +995,9 @@ static void ne10_fft_split_c2r_1d_float32 (ne10_fft_cpx_float32_t *dst,
  *     fftSize = 2^N; //N is 1, 2, 3, 4, 5, 6....
  *     in = (ne10_fft_cpx_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_fft_cpx_float32_t));
  *     out = (ne10_fft_cpx_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_fft_cpx_float32_t));
- *     temp = (ne10_fft_cpx_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_fft_cpx_float32_t));
  *     ne10_fft_cfg_float32_t cfg;
  *     ...
        cfg = ne10_fft_alloc_c2c_float32 (fftSize);
-       cfg->buffer = temp
  *     ...
  *     //FFT
  *     ne10_fft_c2c_1d_float32_c (out, in, cfg, 0);
@@ -1010,7 +1008,6 @@ static void ne10_fft_split_c2r_1d_float32 (ne10_fft_cpx_float32_t *dst,
  *     NE10_FREE (in);
  *     NE10_FREE (out);
  *     NE10_FREE (cfg);
- *     NE10_FREE (temp);
  * }
  * </pre>
  *
@@ -1023,7 +1020,7 @@ static void ne10_fft_split_c2r_1d_float32 (ne10_fft_cpx_float32_t *dst,
  *   \n This is factors buffer: 0: stage number, 1: stride for the first stage, others: factors.
  *   \n For example, 128 could be split into 4x32, 4x8, 4x2, 2x1. The stage is 4, the stride of first stage is <code>128/2 = 64</code>. So that the factor buffer is[4, 64, 4, 32, 4, 8, 4, 2, 2, 1]
  * - cfg->buffer
- *   \n This is pointer to the temp buffer for FFT calculation. This buffer is allocated by the users and the size is (fftSize * sizeof (ne10_fft_cpx_float32_t)).
+ *   \n This is pointer to the temp buffer for FFT calculation. This buffer is allocated in init function and the size is (fftSize * sizeof (ne10_fft_cpx_float32_t)).
  *
  */
 
@@ -1038,19 +1035,21 @@ ne10_fft_cfg_float32_t ne10_fft_alloc_c2c_float32 (ne10_int32_t nfft)
     ne10_fft_cfg_float32_t st = NULL;
     ne10_uint32_t memneeded = sizeof (ne10_fft_state_float32_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors*/
-                              + sizeof (ne10_fft_cpx_float32_t) * (nfft);     /* twiddle*/
+                              + sizeof (ne10_fft_cpx_float32_t) * nfft        /* twiddle*/
+                              + sizeof (ne10_fft_cpx_float32_t) * nfft;       /* buffer*/
 
     st = (ne10_fft_cfg_float32_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_float32_t));
-    st->twiddles = (ne10_fft_cpx_float32_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->nfft = nfft;
 
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_float32_t));
+        st->twiddles = (ne10_fft_cpx_float32_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->buffer = st->twiddles + nfft;
+        st->nfft = nfft;
+
         ne10_int32_t result = ne10_factor (nfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1104,9 +1103,9 @@ ne10_fft_cfg_float32_t ne10_fft_alloc_c2c_float32 (ne10_int32_t nfft)
  * @param[in]   cfg              point to the config struct
  * @param[in]   inverse_fft      the flag of IFFT, 0: FFT, 1: IFFT
  * @return none.
- * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 1, 2, 3, 4, 5, 6 ....etc) is supported.
- * Otherwise, this FFT is an out-of-place algorithm. When you want to get an in-place FFT, it creates a temp buffer as
- *  output buffer and then copies the temp buffer back to input buffer. For the usage of this function, please check test/test_suite_fft_float32.c
+ * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * Otherwise, this FFT is an out-of-place algorithm.
+ * For the usage of this function, please check test/test_suite_fft_float32.c
  */
 void ne10_fft_c2c_1d_float32_c (ne10_fft_cpx_float32_t *fout,
                                 ne10_fft_cpx_float32_t *fin,
@@ -1170,9 +1169,7 @@ void ne10_fft_c2c_1d_float32_c (ne10_fft_cpx_float32_t *fout,
  *     fftSize = 2^N; //N is 2, 3, 4, 5, 6....
  *     in = (ne10_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_float32_t));
  *     out = (ne10_fft_cpx_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_fft_cpx_float32_t));
- *     temp = (ne10_fft_cpx_float32_t*) NE10_MALLOC (fftSize * sizeof (ne10_fft_cpx_float32_t));
  *     ne10_fft_r2c_cfg_float32_t cfg;
- *     cfg->buffer = temp;
  *     ...
        cfg = ne10_fft_alloc_r2c_float32 (fftSize);
  *     ...
@@ -1183,7 +1180,6 @@ void ne10_fft_c2c_1d_float32_c (ne10_fft_cpx_float32_t *fout,
  *     ne10_fft_c2r_1d_float32_c (in, out, cfg);
  *     ...
  *     NE10_FREE (cfg);
- *     NE10_FREE (temp);
  *     NE10_FREE (in);
  *     NE10_FREE (out);
  * }
@@ -1200,7 +1196,7 @@ void ne10_fft_c2c_1d_float32_c (ne10_fft_cpx_float32_t *fout,
  *   \n This is factors buffer: 0: stage number, 1: stride for the first stage, others: factors.
  *   \n For example, 128 could be split into 4x32, 4x8, 4x2, 2x1. The stage is 4, the stride of first stage is <code>128/2 = 64</code>. So that the factor buffer is[4, 64, 4, 32, 4, 8, 4, 2, 2, 1]
  * - cfg->buffer
- *   \n This is pointer to the temp buffer for FFT calculation. This buffer is allocated by the users and the size is (fftSize * sizeof (ne10_fft_cpx_float32_t)).
+ *   \n This is pointer to the temp buffer for FFT calculation. This buffer is allocated in init function and the size is (fftSize * sizeof (ne10_fft_cpx_float32_t)).
  *
  */
 
@@ -1218,20 +1214,22 @@ ne10_fft_r2c_cfg_float32_t ne10_fft_alloc_r2c_float32 (ne10_int32_t nfft)
     ne10_uint32_t memneeded = sizeof (ne10_fft_r2c_state_float32_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors */
                               + sizeof (ne10_fft_cpx_float32_t) * ncfft       /* twiddle*/
-                              + sizeof (ne10_fft_cpx_float32_t) * ncfft / 2;  /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_float32_t) * (ncfft / 2) /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_float32_t) * nfft;      /* buffer*/
 
     st = (ne10_fft_r2c_cfg_float32_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_float32_t));
-    st->twiddles = (ne10_fft_cpx_float32_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->super_twiddles = st->twiddles + ncfft;
-    st->ncfft = ncfft;
 
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_float32_t));
+        st->twiddles = (ne10_fft_cpx_float32_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->super_twiddles = st->twiddles + ncfft;
+        st->buffer = st->super_twiddles + (ncfft / 2);
+        st->ncfft = ncfft;
+
         ne10_int32_t result = ne10_factor (ncfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1293,7 +1291,7 @@ ne10_fft_r2c_cfg_float32_t ne10_fft_alloc_r2c_float32 (ne10_int32_t nfft)
  * @param[in]   *fin             point to the input buffer
  * @param[in]   cfg              point to the config struct
  * @return none.
- * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_float32.c
  */
@@ -1313,7 +1311,7 @@ void ne10_fft_r2c_1d_float32_c (ne10_fft_cpx_float32_t *fout,
  * @param[in]   *fin             point to the input buffer
  * @param[in]   cfg              point to the config struct
  * @return none.
- * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_float32.c
  */
index 7b50cda..96fd9e0 100644 (file)
@@ -572,12 +572,12 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
     float32x4x2_t q2_fk, q2_fnkc, q2_tw, q2_dst, q2_dst2;
     float32x4_t q_fnkc_r, q_fnkc_i;
     float32x4_t q_fek_r, q_fek_i, q_fok_r, q_fok_i;
-    float32x4_t q_tmp0, q_tmp1, q_tmp2, q_tmp3;
+    float32x4_t q_tmp0, q_tmp1, q_tmp2, q_tmp3, q_val;
     float32x4_t q_dst2_r, q_dst2_i;
     float32_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) * 0.5f;
+    dst[0].i = (src[0].r - src[ncfft].r) * 0.5f;
 
     if (count >= 4)
     {
@@ -611,10 +611,15 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
             q_fok_r = vaddq_f32 (q_fok_r, q_tmp2);
             q_fok_i = vsubq_f32 (q_fok_i, q_tmp3);
 
+            q_val = vdupq_n_f32 (0.5f);
             q_dst2_r = vsubq_f32 (q_fek_r, q_fok_r);
             q_dst2_i = vsubq_f32 (q_fok_i, q_fek_i);
             q2_dst.val[0] = vaddq_f32 (q_fek_r, q_fok_r);
             q2_dst.val[1] = vaddq_f32 (q_fek_i, q_fok_i);
+            q_dst2_r = vmulq_f32 (q_dst2_r, q_val);
+            q_dst2_i = vmulq_f32 (q_dst2_i, q_val);
+            q2_dst.val[0] = vmulq_f32 (q2_dst.val[0], q_val);
+            q2_dst.val[1] = vmulq_f32 (q2_dst.val[1], q_val);
             q_dst2_r = vrev64q_f32 (q_dst2_r);
             q_dst2_i = vrev64q_f32 (q_dst2_i);
             q2_dst2.val[0] = vcombine_f32 (vget_high_f32 (q_dst2_r), vget_low_f32 (q_dst2_r));
@@ -641,11 +646,11 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
             fok.r = tmp.r * twiddles[k - 1].r + tmp.i * twiddles[k - 1].i;
             fok.i = tmp.i * twiddles[k - 1].r - tmp.r * twiddles[k - 1].i;
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) * 0.5f;
+            dst[k].i = (fek.i + fok.i) * 0.5f;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) * 0.5f;
+            dst[ncfft - k].i = (fok.i - fek.i) * 0.5f;
         }
     }
 }
index fc26b95..4f06695 100644 (file)
@@ -1550,12 +1550,12 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
     float32x4x2_t q2_fk, q2_fnkc, q2_tw, q2_dst, q2_dst2;
     float32x4_t q_fnkc_r, q_fnkc_i;
     float32x4_t q_fek_r, q_fek_i, q_fok_r, q_fok_i;
-    float32x4_t q_tmp0, q_tmp1, q_tmp2, q_tmp3;
+    float32x4_t q_tmp0, q_tmp1, q_tmp2, q_tmp3, q_val;
     float32x4_t q_dst2_r, q_dst2_i;
     float32_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) * 0.5f;
+    dst[0].i = (src[0].r - src[ncfft].r) * 0.5f;
 
     if (count >= 4)
     {
@@ -1589,10 +1589,15 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
             q_fok_r = vaddq_f32 (q_fok_r, q_tmp2);
             q_fok_i = vsubq_f32 (q_fok_i, q_tmp3);
 
+            q_val = vdupq_n_f32 (0.5f);
             q_dst2_r = vsubq_f32 (q_fek_r, q_fok_r);
             q_dst2_i = vsubq_f32 (q_fok_i, q_fek_i);
             q2_dst.val[0] = vaddq_f32 (q_fek_r, q_fok_r);
             q2_dst.val[1] = vaddq_f32 (q_fek_i, q_fok_i);
+            q_dst2_r = vmulq_f32 (q_dst2_r, q_val);
+            q_dst2_i = vmulq_f32 (q_dst2_i, q_val);
+            q2_dst.val[0] = vmulq_f32 (q2_dst.val[0], q_val);
+            q2_dst.val[1] = vmulq_f32 (q2_dst.val[1], q_val);
             q_dst2_r = vrev64q_f32 (q_dst2_r);
             q_dst2_i = vrev64q_f32 (q_dst2_i);
             q2_dst2.val[0] = vcombine_f32 (vget_high_f32 (q_dst2_r), vget_low_f32 (q_dst2_r));
@@ -1619,11 +1624,11 @@ static void ne10_fft_split_c2r_1d_float32_neon (ne10_fft_cpx_float32_t *dst,
             fok.r = tmp.r * twiddles[k - 1].r + tmp.i * twiddles[k - 1].i;
             fok.i = tmp.i * twiddles[k - 1].r - tmp.r * twiddles[k - 1].i;
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) * 0.5f;
+            dst[k].i = (fek.i + fok.i) * 0.5f;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) * 0.5f;
+            dst[ncfft - k].i = (fok.i - fek.i) * 0.5f;
         }
     }
 }
index 713c978..e183e61 100644 (file)
@@ -1037,8 +1037,8 @@ static void ne10_fft_split_c2r_1d_int16 (ne10_fft_cpx_int16_t *dst,
     ne10_fft_cpx_int16_t fk, fnkc, fek, fok, tmp;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
 
     if (scaled_flag)
         NE10_F2I16_FIXDIV (dst[0], 2);
@@ -1065,11 +1065,11 @@ static void ne10_fft_split_c2r_1d_int16 (ne10_fft_cpx_int16_t *dst,
         fok.i = (ne10_int16_t) ( ( (NE10_F2I16_SAMPPROD) tmp.i * (twiddles[k - 1]).r
                                    - (NE10_F2I16_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> NE10_F2I16_SHIFT);
 
-        dst[k].r = fek.r + fok.r;
-        dst[k].i = fek.i + fok.i;
+        dst[k].r = (fek.r + fok.r) >> 1;
+        dst[k].i = (fek.i + fok.i) >> 1;
 
-        dst[ncfft - k].r = fek.r - fok.r;
-        dst[ncfft - k].i = fok.i - fek.i;
+        dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+        dst[ncfft - k].i = (fok.i - fek.i) >> 1;
     }
 }
 
@@ -1089,19 +1089,21 @@ ne10_fft_cfg_int16_t ne10_fft_alloc_c2c_int16 (ne10_int32_t nfft)
     ne10_fft_cfg_int16_t st = NULL;
     ne10_uint32_t memneeded = sizeof (ne10_fft_state_int16_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors */
-                              + sizeof (ne10_fft_cpx_int16_t) * (nfft);       /* twiddle */
+                              + sizeof (ne10_fft_cpx_int16_t) * (nfft)        /* twiddle */
+                              + sizeof (ne10_fft_cpx_int16_t) * nfft;         /* buffer */
 
     st = (ne10_fft_cfg_int16_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_int16_t));
-    st->twiddles = (ne10_fft_cpx_int16_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->nfft = nfft;
 
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_int16_t));
+        st->twiddles = (ne10_fft_cpx_int16_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->buffer = st->twiddles + nfft;
+        st->nfft = nfft;
+
         ne10_int32_t result = ne10_factor (nfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1156,9 +1158,8 @@ ne10_fft_cfg_int16_t ne10_fft_alloc_c2c_int16 (ne10_int32_t nfft)
  * @param[in]   inverse_fft      the flag of IFFT, 0: FFT, 1: IFFT
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 1, 2, 3, 4, 5, 6 ....etc) is supported.
- * Otherwise, this FFT is an out-of-place algorithm. When you want to get an in-place FFT, it creates a temp buffer as
- *  output buffer and then copies the temp buffer back to input buffer. For the usage of this function, please check test/test_suite_fft_int16.c
+ * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * Otherwise, this FFT is an out-of-place algorithm. For the usage of this function, please check test/test_suite_fft_int16.c
  */
 void ne10_fft_c2c_1d_int16_c (ne10_fft_cpx_int16_t *fout,
                               ne10_fft_cpx_int16_t *fin,
@@ -1198,20 +1199,22 @@ ne10_fft_r2c_cfg_int16_t ne10_fft_alloc_r2c_int16 (ne10_int32_t nfft)
     ne10_uint32_t memneeded = sizeof (ne10_fft_r2c_state_int16_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors */
                               + sizeof (ne10_fft_cpx_int16_t) * ncfft         /* twiddle*/
-                              + sizeof (ne10_fft_cpx_int16_t) * ncfft / 2;    /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_int16_t) * ncfft / 2     /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_int32_t) * nfft;         /* buffer*/
 
     st = (ne10_fft_r2c_cfg_int16_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_int16_t));
-    st->twiddles = (ne10_fft_cpx_int16_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->super_twiddles = st->twiddles + ncfft;
-    st->ncfft = ncfft;
 
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_int16_t));
+        st->twiddles = (ne10_fft_cpx_int16_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->super_twiddles = st->twiddles + ncfft;
+        st->buffer = st->super_twiddles + (ncfft / 2);
+        st->ncfft = ncfft;
+
         ne10_int32_t result = ne10_factor (ncfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1274,7 +1277,7 @@ ne10_fft_r2c_cfg_int16_t ne10_fft_alloc_r2c_int16 (ne10_int32_t nfft)
  * @param[in]   cfg              point to the config struct
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_int16.c
  */
@@ -1296,7 +1299,7 @@ void ne10_fft_r2c_1d_int16_c (ne10_fft_cpx_int16_t *fout,
  * @param[in]   cfg              point to the config struct
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_int16.c
  */
index 05ace88..180ec1c 100644 (file)
@@ -585,8 +585,8 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
     int16_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
 
     if (scaled_flag)
         NE10_F2I16_FIXDIV (dst[0], 2);
@@ -625,10 +625,10 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
                 q_fok_r = vaddq_s16 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s16 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s16 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s16 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s16 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s16 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s16 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s16 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s16 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s16 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev32q_s16 (q_dst2_r);
                 q_dst2_i = vrev32q_s16 (q_dst2_i);
                 q_dst2_r = vreinterpretq_s16_s32 (vrev64q_s32 (vreinterpretq_s32_s16 (q_dst2_r))) ;
@@ -674,10 +674,10 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
                 q_fok_r = vaddq_s16 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s16 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s16 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s16 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s16 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s16 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s16 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s16 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s16 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s16 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev32q_s16 (q_dst2_r);
                 q_dst2_i = vrev32q_s16 (q_dst2_i);
                 q_dst2_r = vreinterpretq_s16_s32 (vrev64q_s32 (vreinterpretq_s32_s16 (q_dst2_r))) ;
@@ -715,11 +715,11 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
             fok.i = (ne10_int16_t) ( ( (NE10_F2I16_SAMPPROD) tmp.i * (twiddles[k - 1]).r
                                        - (NE10_F2I16_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> NE10_F2I16_SHIFT);
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) >> 1;
+            dst[k].i = (fek.i + fok.i) >> 1;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+            dst[ncfft - k].i = (fok.i - fek.i) >> 1;
         }
     }
 }
index c51099b..d8101c9 100644 (file)
@@ -1404,8 +1404,8 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
     int16_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
 
     if (scaled_flag)
         NE10_F2I16_FIXDIV (dst[0], 2);
@@ -1444,10 +1444,10 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
                 q_fok_r = vaddq_s16 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s16 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s16 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s16 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s16 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s16 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s16 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s16 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s16 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s16 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev32q_s16 (q_dst2_r);
                 q_dst2_i = vrev32q_s16 (q_dst2_i);
                 q_dst2_r = vreinterpretq_s16_s32 (vrev64q_s32 (vreinterpretq_s32_s16 (q_dst2_r))) ;
@@ -1493,10 +1493,10 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
                 q_fok_r = vaddq_s16 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s16 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s16 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s16 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s16 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s16 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s16 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s16 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s16 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s16 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev32q_s16 (q_dst2_r);
                 q_dst2_i = vrev32q_s16 (q_dst2_i);
                 q_dst2_r = vreinterpretq_s16_s32 (vrev64q_s32 (vreinterpretq_s32_s16 (q_dst2_r))) ;
@@ -1534,11 +1534,11 @@ static void ne10_fft_split_c2r_1d_int16_neon (ne10_fft_cpx_int16_t *dst,
             fok.i = (ne10_int16_t) ( ( (NE10_F2I16_SAMPPROD) tmp.i * (twiddles[k - 1]).r
                                        - (NE10_F2I16_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> NE10_F2I16_SHIFT);
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) >> 1;
+            dst[k].i = (fek.i + fok.i) >> 1;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+            dst[ncfft - k].i = (fok.i - fek.i) >> 1;
         }
     }
 }
index 916c5a4..8a5a302 100644 (file)
@@ -1036,8 +1036,8 @@ static void ne10_fft_split_c2r_1d_int32 (ne10_fft_cpx_int32_t *dst,
     ne10_fft_cpx_int32_t fk, fnkc, fek, fok, tmp;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
 
     if (scaled_flag)
         NE10_F2I32_FIXDIV (dst[0], 2);
@@ -1062,11 +1062,11 @@ static void ne10_fft_split_c2r_1d_int32 (ne10_fft_cpx_int32_t *dst,
         fok.r = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).r) >> 32)) + ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).i) >> 32))) << 1;
         fok.i = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).r) >> 32)) - ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> 32))) << 1;
 
-        dst[k].r = fek.r + fok.r;
-        dst[k].i = fek.i + fok.i;
+        dst[k].r = (fek.r + fok.r) >> 1;
+        dst[k].i = (fek.i + fok.i) >> 1;
 
-        dst[ncfft - k].r = fek.r - fok.r;
-        dst[ncfft - k].i = fok.i - fek.i;
+        dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+        dst[ncfft - k].i = (fok.i - fek.i) >> 1;
     }
 }
 
@@ -1087,18 +1087,20 @@ ne10_fft_cfg_int32_t ne10_fft_alloc_c2c_int32 (ne10_int32_t nfft)
     ne10_fft_cfg_int32_t st = NULL;
     ne10_uint32_t memneeded = sizeof (ne10_fft_state_int32_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors */
-                              + sizeof (ne10_fft_cpx_int32_t) * (nfft);       /* twiddle */
+                              + sizeof (ne10_fft_cpx_int32_t) * nfft          /* twiddle */
+                              + sizeof (ne10_fft_cpx_int32_t) * nfft;         /* buffer */
 
     st = (ne10_fft_cfg_int32_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_int32_t));
-    st->twiddles = (ne10_fft_cpx_int32_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->nfft = nfft;
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_state_int32_t));
+        st->twiddles = (ne10_fft_cpx_int32_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->buffer = st->twiddles + nfft;
+        st->nfft = nfft;
+
         ne10_int32_t result = ne10_factor (nfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1153,9 +1155,8 @@ ne10_fft_cfg_int32_t ne10_fft_alloc_c2c_int32 (ne10_int32_t nfft)
  * @param[in]   inverse_fft      the flag of IFFT, 0: FFT, 1: IFFT
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
- * Otherwise, this FFT is an out-of-place algorithm. When you want to get an in-place FFT, it creates a temp buffer as
- *  output buffer and then copies the temp buffer back to input buffer. For the usage of this function, please check test/test_suite_fft_int32.c
+ * The function implements a mixed radix-2/4 complex FFT/IFFT. The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * Otherwise, this FFT is an out-of-place algorithm. For the usage of this function, please check test/test_suite_fft_int32.c
  */
 void ne10_fft_c2c_1d_int32_c (ne10_fft_cpx_int32_t *fout,
                               ne10_fft_cpx_int32_t *fin,
@@ -1193,20 +1194,22 @@ ne10_fft_r2c_cfg_int32_t ne10_fft_alloc_r2c_int32 (ne10_int32_t nfft)
     ne10_uint32_t memneeded = sizeof (ne10_fft_r2c_state_int32_t)
                               + sizeof (ne10_int32_t) * (NE10_MAXFACTORS * 2) /* factors */
                               + sizeof (ne10_fft_cpx_int32_t) * ncfft         /* twiddle*/
-                              + sizeof (ne10_fft_cpx_int32_t) * ncfft / 2;    /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_int32_t) * ncfft / 2     /* super twiddles*/
+                              + sizeof (ne10_fft_cpx_int32_t) * nfft;         /* buffer*/
 
     st = (ne10_fft_r2c_cfg_int32_t) NE10_MALLOC (memneeded);
-    st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_int32_t));
-    st->twiddles = (ne10_fft_cpx_int32_t*) (st->factors + (NE10_MAXFACTORS * 2));
-    st->super_twiddles = st->twiddles + ncfft;
-    st->ncfft = ncfft;
 
     if (st)
     {
+        st->factors = (ne10_int32_t*) ( (ne10_int8_t*) st + sizeof (ne10_fft_r2c_state_int32_t));
+        st->twiddles = (ne10_fft_cpx_int32_t*) (st->factors + (NE10_MAXFACTORS * 2));
+        st->super_twiddles = st->twiddles + ncfft;
+        st->buffer = st->super_twiddles + (ncfft / 2);
+        st->ncfft = ncfft;
+
         ne10_int32_t result = ne10_factor (ncfft, st->factors);
         if (result == NE10_ERR)
         {
-            fprintf (stdout, "======ERROR, the length of FFT isn't support\n");
             NE10_FREE (st);
             return st;
         }
@@ -1269,7 +1272,7 @@ ne10_fft_r2c_cfg_int32_t ne10_fft_alloc_r2c_int32 (ne10_int32_t nfft)
  * @param[in]   cfg              point to the config struct
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (real to complex). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_int32.c
  */
@@ -1292,7 +1295,7 @@ void ne10_fft_r2c_1d_int32_c (ne10_fft_cpx_int32_t *fout,
  * @param[in]   cfg              point to the config struct
  * @param[in]   scaled_flag      scale flag, 0 unscaled, 1 scaled
  * @return none.
- * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 2, 3, 4, 5, 6 ....etc) is supported.
+ * The function implements a mixed radix-2/4 FFT (complex to real). The length of 2^N(N is 3, 4, 5, 6 ....etc) is supported.
  * Otherwise, we alloc a temp buffer(the size is same as input buffer) for storing intermedia.
  * For the usage of this function, please check test/test_suite_fft_int32.c
  */
index 9c7b93d..485c69e 100644 (file)
@@ -1084,8 +1084,8 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
     int32_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
     if (scaled_flag)
         NE10_F2I32_FIXDIV (dst[0], 2);
     if (count >= 4)
@@ -1121,10 +1121,10 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
                 q_fok_r = vaddq_s32 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s32 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s32 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s32 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s32 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s32 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s32 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s32 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s32 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s32 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev64q_s32 (q_dst2_r);
                 q_dst2_i = vrev64q_s32 (q_dst2_i);
                 q2_dst2.val[0] = vcombine_s32 (vget_high_s32 (q_dst2_r), vget_low_s32 (q_dst2_r));
@@ -1166,10 +1166,10 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
                 q_fok_r = vaddq_s32 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s32 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s32 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s32 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s32 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s32 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s32 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s32 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s32 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s32 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev64q_s32 (q_dst2_r);
                 q_dst2_i = vrev64q_s32 (q_dst2_i);
                 q2_dst2.val[0] = vcombine_s32 (vget_high_s32 (q_dst2_r), vget_low_s32 (q_dst2_r));
@@ -1203,11 +1203,11 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
             fok.r = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).r) >> 32)) + ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).i) >> 32))) << 1;
             fok.i = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).r) >> 32)) - ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> 32))) << 1;
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) >> 1;
+            dst[k].i = (fek.i + fok.i) >> 1;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+            dst[ncfft - k].i = (fok.i - fek.i) >> 1;
         }
     }
 }
index e8a14c8..2c71d9c 100644 (file)
@@ -1695,8 +1695,8 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
     int32_t *p_src, *p_src2, *p_dst, *p_dst2, *p_twiddles;
 
 
-    dst[0].r = src[0].r + src[ncfft].r;
-    dst[0].i = src[0].r - src[ncfft].r;
+    dst[0].r = (src[0].r + src[ncfft].r) >> 1;
+    dst[0].i = (src[0].r - src[ncfft].r) >> 1;
     if (scaled_flag)
         NE10_F2I32_FIXDIV (dst[0], 2);
     if (count >= 4)
@@ -1732,10 +1732,10 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
                 q_fok_r = vaddq_s32 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s32 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s32 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s32 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s32 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s32 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s32 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s32 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s32 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s32 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev64q_s32 (q_dst2_r);
                 q_dst2_i = vrev64q_s32 (q_dst2_i);
                 q2_dst2.val[0] = vcombine_s32 (vget_high_s32 (q_dst2_r), vget_low_s32 (q_dst2_r));
@@ -1777,10 +1777,10 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
                 q_fok_r = vaddq_s32 (q_fok_r, q_tmp2);
                 q_fok_i = vsubq_s32 (q_fok_i, q_tmp3);
 
-                q_dst2_r = vsubq_s32 (q_fek_r, q_fok_r);
-                q_dst2_i = vsubq_s32 (q_fok_i, q_fek_i);
-                q2_dst.val[0] = vaddq_s32 (q_fek_r, q_fok_r);
-                q2_dst.val[1] = vaddq_s32 (q_fek_i, q_fok_i);
+                q_dst2_r = vhsubq_s32 (q_fek_r, q_fok_r);
+                q_dst2_i = vhsubq_s32 (q_fok_i, q_fek_i);
+                q2_dst.val[0] = vhaddq_s32 (q_fek_r, q_fok_r);
+                q2_dst.val[1] = vhaddq_s32 (q_fek_i, q_fok_i);
                 q_dst2_r = vrev64q_s32 (q_dst2_r);
                 q_dst2_i = vrev64q_s32 (q_dst2_i);
                 q2_dst2.val[0] = vcombine_s32 (vget_high_s32 (q_dst2_r), vget_low_s32 (q_dst2_r));
@@ -1814,11 +1814,11 @@ static void ne10_fft_split_c2r_1d_int32_neon (ne10_fft_cpx_int32_t *dst,
             fok.r = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).r) >> 32)) + ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).i) >> 32))) << 1;
             fok.i = ( ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.i * (twiddles[k - 1]).r) >> 32)) - ( (ne10_int32_t) ( ( (NE10_F2I32_SAMPPROD) tmp.r * (twiddles[k - 1]).i) >> 32))) << 1;
 
-            dst[k].r = fek.r + fok.r;
-            dst[k].i = fek.i + fok.i;
+            dst[k].r = (fek.r + fok.r) >> 1;
+            dst[k].i = (fek.i + fok.i) >> 1;
 
-            dst[ncfft - k].r = fek.r - fok.r;
-            dst[ncfft - k].i = fok.i - fek.i;
+            dst[ncfft - k].r = (fek.r - fok.r) >> 1;
+            dst[ncfft - k].i = (fok.i - fek.i) >> 1;
         }
     }
 }
index 2bec27a..8861583 100644 (file)
@@ -72,8 +72,6 @@ static ne10_float32_t * guarded_out_neon = NULL;
 static ne10_float32_t * out_c = NULL;
 static ne10_float32_t * out_neon = NULL;
 
-static ne10_float32_t * temp = NULL;
-
 static ne10_float32_t snr = 0.0f;
 
 static ne10_int64_t time_c = 0;
@@ -102,9 +100,6 @@ void test_fft_c2c_1d_float32_conformance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_f32[i] = (ne10_float32_t) (drand48() * 32768.0f - 16384.0f);
@@ -117,7 +112,11 @@ void test_fft_c2c_1d_float32_conformance()
         memcpy (in_c, testInput_f32, 2 * fftSize * sizeof (ne10_float32_t));
         memcpy (in_neon, testInput_f32, 2 * fftSize * sizeof (ne10_float32_t));
         cfg = ne10_fft_alloc_c2c_float32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_float32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         GUARD_ARRAY (out_c, fftSize * 2);
         GUARD_ARRAY (out_neon, fftSize * 2);
@@ -156,7 +155,6 @@ void test_fft_c2c_1d_float32_conformance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_c2c_1d_float32_performance()
@@ -182,9 +180,6 @@ void test_fft_c2c_1d_float32_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_f32[i] = (ne10_float32_t) drand48() * 2 ;
@@ -197,7 +192,11 @@ void test_fft_c2c_1d_float32_performance()
         memcpy (in_c, testInput_f32, 2 * fftSize * sizeof (ne10_float32_t));
         memcpy (in_neon, testInput_f32, 2 * fftSize * sizeof (ne10_float32_t));
         cfg = ne10_fft_alloc_c2c_float32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_float32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
 
         GET_TIME
@@ -253,7 +252,6 @@ void test_fft_c2c_1d_float32_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_float32_conformance()
@@ -277,9 +275,6 @@ void test_fft_r2c_1d_float32_conformance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_f32[i] = (ne10_float32_t) (drand48() * 32768.0f - 16384.0f);
@@ -292,7 +287,11 @@ void test_fft_r2c_1d_float32_conformance()
         memcpy (in_c, testInput_f32, fftSize * sizeof (ne10_float32_t));
         memcpy (in_neon, testInput_f32, fftSize * sizeof (ne10_float32_t));
         cfg = ne10_fft_alloc_r2c_float32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_float32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         GUARD_ARRAY (out_c, (fftSize / 2 + 1) * 2);
         GUARD_ARRAY (out_neon, (fftSize / 2 + 1) * 2);
@@ -341,7 +340,6 @@ void test_fft_r2c_1d_float32_conformance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_float32_performance()
@@ -367,9 +365,6 @@ void test_fft_r2c_1d_float32_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_f32[i] = (ne10_float32_t) (drand48() * 32768.0f - 16384.0f);
@@ -382,7 +377,11 @@ void test_fft_r2c_1d_float32_performance()
         memcpy (in_c, testInput_f32, fftSize * sizeof (ne10_float32_t));
         memcpy (in_neon, testInput_f32, fftSize * sizeof (ne10_float32_t));
         cfg = ne10_fft_alloc_r2c_float32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_float32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
 
         GET_TIME
@@ -448,7 +447,6 @@ void test_fft_r2c_1d_float32_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 static void my_test_setup (void)
index 9766cbd..2358d4a 100644 (file)
@@ -69,8 +69,6 @@ static ne10_int16_t * guarded_out_neon = NULL;
 static ne10_int16_t * out_c = NULL;
 static ne10_int16_t * out_neon = NULL;
 
-static ne10_int16_t * temp = NULL;
-
 static ne10_float32_t snr = 0.0f;
 
 static ne10_int64_t time_c = 0;
@@ -106,9 +104,6 @@ void test_fft_c2c_1d_int16_conformance()
     out_c_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
     out_neon_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
 
-    /* init temp memory */
-    temp = (ne10_int16_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int16_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i16_unscaled[i] = (ne10_int32_t) (drand48() * 1024) - 512;
@@ -118,7 +113,11 @@ void test_fft_c2c_1d_int16_conformance()
     {
         fprintf (stdout, "FFT size %d\n", fftSize);
         cfg = ne10_fft_alloc_c2c_int16 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int16_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         /* unscaled FFT test */
         memcpy (in_c, testInput_i16_unscaled, 2 * fftSize * sizeof (ne10_int16_t));
@@ -217,7 +216,6 @@ void test_fft_c2c_1d_int16_conformance()
     NE10_FREE (guarded_out_neon);
     NE10_FREE (out_c_tmp);
     NE10_FREE (out_neon_tmp);
-    NE10_FREE (temp);
 }
 
 void test_fft_c2c_1d_int16_performance()
@@ -243,9 +241,6 @@ void test_fft_c2c_1d_int16_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_int16_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int16_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i16_unscaled[i] = (ne10_int16_t) (drand48() * 1024) - 512;
@@ -255,7 +250,11 @@ void test_fft_c2c_1d_int16_performance()
     {
         fprintf (stdout, "FFT size %d\n", fftSize);
         cfg = ne10_fft_alloc_c2c_int16 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int16_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
 
         /* unscaled FFT test */
@@ -364,7 +363,6 @@ void test_fft_c2c_1d_int16_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_int16_conformance()
@@ -393,9 +391,6 @@ void test_fft_r2c_1d_int16_conformance()
     out_c_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
     out_neon_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
 
-    /* init temp memory */
-    temp = (ne10_int16_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int16_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i16_unscaled[i] = (ne10_int16_t) (drand48() * 1024) - 512;
@@ -405,7 +400,11 @@ void test_fft_r2c_1d_int16_conformance()
     {
         fprintf (stdout, "RFFT size %d\n", fftSize);
         cfg = ne10_fft_alloc_r2c_int16 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int16_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         /* unscaled FFT test */
         memcpy (in_c, testInput_i16_unscaled, fftSize * sizeof (ne10_int16_t));
@@ -524,7 +523,6 @@ void test_fft_r2c_1d_int16_conformance()
     NE10_FREE (guarded_out_neon);
     NE10_FREE (out_c_tmp);
     NE10_FREE (out_neon_tmp);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_int16_performance()
@@ -550,9 +548,6 @@ void test_fft_r2c_1d_int16_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_int16_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int16_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i16_unscaled[i] = (ne10_int16_t) (drand48() * 1024) - 512;
@@ -562,7 +557,11 @@ void test_fft_r2c_1d_int16_performance()
     {
         fprintf (stdout, "FFT size %d\n", fftSize);
         cfg = ne10_fft_alloc_r2c_int16 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int16_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
 
         /* unscaled FFT test */
@@ -692,7 +691,6 @@ void test_fft_r2c_1d_int16_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_c2c_1d_int16()
index 53010f4..0c65cd8 100644 (file)
@@ -69,8 +69,6 @@ static ne10_int32_t * guarded_out_neon = NULL;
 static ne10_int32_t * out_c = NULL;
 static ne10_int32_t * out_neon = NULL;
 
-static ne10_int32_t * temp = NULL;
-
 static ne10_float32_t snr = 0.0f;
 
 static ne10_int64_t time_c = 0;
@@ -106,9 +104,6 @@ void test_fft_c2c_1d_int32_conformance()
     out_c_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
     out_neon_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
 
-    /* init temp memory */
-    temp = (ne10_int32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i32_unscaled[i] = (ne10_int32_t) (drand48() * 8192) - 4096;
@@ -119,7 +114,11 @@ void test_fft_c2c_1d_int32_conformance()
         fprintf (stdout, "FFT size %d\n", fftSize);
         /* FFT init */
         cfg = ne10_fft_alloc_c2c_int32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         /* unscaled FFT test */
         memcpy (in_c, testInput_i32_unscaled, 2 * fftSize * sizeof (ne10_int32_t));
@@ -210,7 +209,6 @@ void test_fft_c2c_1d_int32_conformance()
     NE10_FREE (guarded_out_neon);
     NE10_FREE (out_c_tmp);
     NE10_FREE (out_neon_tmp);
-    NE10_FREE (temp);
 }
 
 void test_fft_c2c_1d_int32_performance()
@@ -236,9 +234,6 @@ void test_fft_c2c_1d_int32_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_int32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i32_unscaled[i] = (ne10_int32_t) (drand48() * 8192) - 4096;
@@ -252,7 +247,11 @@ void test_fft_c2c_1d_int32_performance()
         memcpy (in_c, testInput_i32_unscaled, 2 * fftSize * sizeof (ne10_int32_t));
         memcpy (in_neon, testInput_i32_unscaled, 2 * fftSize * sizeof (ne10_int32_t));
         cfg = ne10_fft_alloc_c2c_int32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
 
         GET_TIME
@@ -356,7 +355,6 @@ void test_fft_c2c_1d_int32_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_int32_conformance()
@@ -385,9 +383,6 @@ void test_fft_r2c_1d_int32_conformance()
     out_c_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
     out_neon_tmp = (ne10_float32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_float32_t));
 
-    /* init temp memory */
-    temp = (ne10_int32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i32_unscaled[i] = (ne10_int32_t) (drand48() * 8192) - 4096;
@@ -398,7 +393,11 @@ void test_fft_r2c_1d_int32_conformance()
         fprintf (stdout, "FFT size %d\n", fftSize);
         /* FFT init */
         cfg = ne10_fft_alloc_r2c_int32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
 
         /* unscaled FFT test */
         memcpy (in_c, testInput_i32_unscaled, fftSize * sizeof (ne10_int32_t));
@@ -518,7 +517,6 @@ void test_fft_r2c_1d_int32_conformance()
     NE10_FREE (guarded_out_neon);
     NE10_FREE (out_c_tmp);
     NE10_FREE (out_neon_tmp);
-    NE10_FREE (temp);
 }
 
 void test_fft_r2c_1d_int32_performance()
@@ -544,9 +542,6 @@ void test_fft_r2c_1d_int32_performance()
     out_c = guarded_out_c + ARRAY_GUARD_LEN;
     out_neon = guarded_out_neon + ARRAY_GUARD_LEN;
 
-    /* init temp memory */
-    temp = (ne10_int32_t*) NE10_MALLOC ( (TEST_LENGTH_SAMPLES * 2) * sizeof (ne10_int32_t));
-
     for (i = 0; i < TEST_LENGTH_SAMPLES * 2; i++)
     {
         testInput_i32_unscaled[i] = (ne10_int32_t) (drand48() * 8192) - 4096;
@@ -557,7 +552,11 @@ void test_fft_r2c_1d_int32_performance()
         fprintf (stdout, "FFT size %d\n", fftSize);
 
         cfg = ne10_fft_alloc_r2c_int32 (fftSize);
-        cfg->buffer = (ne10_fft_cpx_int32_t*)temp;
+        if (cfg == NULL)
+        {
+            fprintf (stdout, "======ERROR, FFT alloc fails\n");
+            return;
+        }
         test_loop = TEST_COUNT / fftSize;
         /* unscaled FFT test */
         memcpy (in_c, testInput_i32_unscaled, fftSize * sizeof (ne10_int32_t));
@@ -686,7 +685,6 @@ void test_fft_r2c_1d_int32_performance()
     NE10_FREE (guarded_in_neon);
     NE10_FREE (guarded_out_c);
     NE10_FREE (guarded_out_neon);
-    NE10_FREE (temp);
 }
 
 void test_fft_c2c_1d_int32()