arm_rfft_fast_f64.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* ----------------------------------------------------------------------
  2. * Project: CMSIS DSP Library
  3. * Title: arm_rfft_fast_f64.c
  4. * Description: RFFT & RIFFT Double precision Floating point process function
  5. *
  6. * $Date: 23 April 2021
  7. * $Revision: V1.9.0
  8. *
  9. * Target Processor: Cortex-M and Cortex-A cores
  10. * -------------------------------------------------------------------- */
  11. /*
  12. * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
  13. *
  14. * SPDX-License-Identifier: Apache-2.0
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the License); you may
  17. * not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. #include "dsp/transform_functions.h"
  29. void stage_rfft_f64(
  30. const arm_rfft_fast_instance_f64 * S,
  31. float64_t * p,
  32. float64_t * pOut)
  33. {
  34. uint32_t k; /* Loop Counter */
  35. float64_t twR, twI; /* RFFT Twiddle coefficients */
  36. const float64_t * pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
  37. float64_t *pA = p; /* increasing pointer */
  38. float64_t *pB = p; /* decreasing pointer */
  39. float64_t xAR, xAI, xBR, xBI; /* temporary variables */
  40. float64_t t1a, t1b; /* temporary variables */
  41. float64_t p0, p1, p2, p3; /* temporary variables */
  42. k = (S->Sint).fftLen - 1;
  43. /* Pack first and last sample of the frequency domain together */
  44. xBR = pB[0];
  45. xBI = pB[1];
  46. xAR = pA[0];
  47. xAI = pA[1];
  48. twR = *pCoeff++ ;
  49. twI = *pCoeff++ ;
  50. // U1 = XA(1) + XB(1); % It is real
  51. t1a = xBR + xAR ;
  52. // U2 = XB(1) - XA(1); % It is imaginary
  53. t1b = xBI + xAI ;
  54. // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
  55. // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
  56. *pOut++ = 0.5 * ( t1a + t1b );
  57. *pOut++ = 0.5 * ( t1a - t1b );
  58. // XA(1) = 1/2*( U1 - imag(U2) + i*( U1 +imag(U2) ));
  59. pB = p + 2*k;
  60. pA += 2;
  61. do
  62. {
  63. /*
  64. function X = my_split_rfft(X, ifftFlag)
  65. % X is a series of real numbers
  66. L = length(X);
  67. XC = X(1:2:end) +i*X(2:2:end);
  68. XA = fft(XC);
  69. XB = conj(XA([1 end:-1:2]));
  70. TW = i*exp(-2*pi*i*[0:L/2-1]/L).';
  71. for l = 2:L/2
  72. XA(l) = 1/2 * (XA(l) + XB(l) + TW(l) * (XB(l) - XA(l)));
  73. end
  74. XA(1) = 1/2* (XA(1) + XB(1) + TW(1) * (XB(1) - XA(1))) + i*( 1/2*( XA(1) + XB(1) + i*( XA(1) - XB(1))));
  75. X = XA;
  76. */
  77. xBI = pB[1];
  78. xBR = pB[0];
  79. xAR = pA[0];
  80. xAI = pA[1];
  81. twR = *pCoeff++;
  82. twI = *pCoeff++;
  83. t1a = xBR - xAR ;
  84. t1b = xBI + xAI ;
  85. // real(tw * (xB - xA)) = twR * (xBR - xAR) - twI * (xBI - xAI);
  86. // imag(tw * (xB - xA)) = twI * (xBR - xAR) + twR * (xBI - xAI);
  87. p0 = twR * t1a;
  88. p1 = twI * t1a;
  89. p2 = twR * t1b;
  90. p3 = twI * t1b;
  91. *pOut++ = 0.5 * (xAR + xBR + p0 + p3 ); //xAR
  92. *pOut++ = 0.5 * (xAI - xBI + p1 - p2 ); //xAI
  93. pA += 2;
  94. pB -= 2;
  95. k--;
  96. } while (k > 0U);
  97. }
  98. /* Prepares data for inverse cfft */
  99. void merge_rfft_f64(
  100. const arm_rfft_fast_instance_f64 * S,
  101. float64_t * p,
  102. float64_t * pOut)
  103. {
  104. uint32_t k; /* Loop Counter */
  105. float64_t twR, twI; /* RFFT Twiddle coefficients */
  106. const float64_t *pCoeff = S->pTwiddleRFFT; /* Points to RFFT Twiddle factors */
  107. float64_t *pA = p; /* increasing pointer */
  108. float64_t *pB = p; /* decreasing pointer */
  109. float64_t xAR, xAI, xBR, xBI; /* temporary variables */
  110. float64_t t1a, t1b, r, s, t, u; /* temporary variables */
  111. k = (S->Sint).fftLen - 1;
  112. xAR = pA[0];
  113. xAI = pA[1];
  114. pCoeff += 2 ;
  115. *pOut++ = 0.5 * ( xAR + xAI );
  116. *pOut++ = 0.5 * ( xAR - xAI );
  117. pB = p + 2*k ;
  118. pA += 2 ;
  119. while (k > 0U)
  120. {
  121. /* G is half of the frequency complex spectrum */
  122. //for k = 2:N
  123. // Xk(k) = 1/2 * (G(k) + conj(G(N-k+2)) + Tw(k)*( G(k) - conj(G(N-k+2))));
  124. xBI = pB[1] ;
  125. xBR = pB[0] ;
  126. xAR = pA[0];
  127. xAI = pA[1];
  128. twR = *pCoeff++;
  129. twI = *pCoeff++;
  130. t1a = xAR - xBR ;
  131. t1b = xAI + xBI ;
  132. r = twR * t1a;
  133. s = twI * t1b;
  134. t = twI * t1a;
  135. u = twR * t1b;
  136. // real(tw * (xA - xB)) = twR * (xAR - xBR) - twI * (xAI - xBI);
  137. // imag(tw * (xA - xB)) = twI * (xAR - xBR) + twR * (xAI - xBI);
  138. *pOut++ = 0.5 * (xAR + xBR - r - s ); //xAR
  139. *pOut++ = 0.5 * (xAI - xBI + t - u ); //xAI
  140. pA += 2;
  141. pB -= 2;
  142. k--;
  143. }
  144. }
  145. /**
  146. @ingroup groupTransforms
  147. */
  148. /**
  149. @addtogroup RealFFT
  150. @{
  151. */
  152. /**
  153. @brief Processing function for the Double Precision floating-point real FFT.
  154. @param[in] S points to an arm_rfft_fast_instance_f64 structure
  155. @param[in] p points to input buffer (Source buffer is modified by this function.)
  156. @param[in] pOut points to output buffer
  157. @param[in] ifftFlag
  158. - value = 0: RFFT
  159. - value = 1: RIFFT
  160. @return none
  161. */
  162. void arm_rfft_fast_f64(
  163. arm_rfft_fast_instance_f64 * S,
  164. float64_t * p,
  165. float64_t * pOut,
  166. uint8_t ifftFlag)
  167. {
  168. arm_cfft_instance_f64 * Sint = &(S->Sint);
  169. Sint->fftLen = S->fftLenRFFT / 2;
  170. /* Calculation of Real FFT */
  171. if (ifftFlag)
  172. {
  173. /* Real FFT compression */
  174. merge_rfft_f64(S, p, pOut);
  175. /* Complex radix-4 IFFT process */
  176. arm_cfft_f64( Sint, pOut, ifftFlag, 1);
  177. }
  178. else
  179. {
  180. /* Calculation of RFFT of input */
  181. arm_cfft_f64( Sint, p, ifftFlag, 1);
  182. /* Real FFT extraction */
  183. stage_rfft_f64(S, p, pOut);
  184. }
  185. }
  186. /**
  187. * @} end of RealFFT group
  188. */