1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_bitreversal.c
4 * Description: Bitreversal functions
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
29 #include "dsp/transform_functions.h"
30 #include "arm_common_tables.h"
31
32 void arm_bitreversal_f32(
33 float32_t * pSrc,
34 uint16_t fftSize,
35 uint16_t bitRevFactor,
36 const uint16_t * pBitRevTab);
37
38 /**
39 @brief In-place floating-point bit reversal function.
40 @param[in,out] pSrc points to in-place floating-point data buffer
41 @param[in] fftSize length of FFT
42 @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
43 @param[in] pBitRevTab points to bit reversal table
44 */
45
arm_bitreversal_f32(float32_t * pSrc,uint16_t fftSize,uint16_t bitRevFactor,const uint16_t * pBitRevTab)46 ARM_DSP_ATTRIBUTE void arm_bitreversal_f32(
47 float32_t * pSrc,
48 uint16_t fftSize,
49 uint16_t bitRevFactor,
50 const uint16_t * pBitRevTab)
51 {
52 uint16_t fftLenBy2, fftLenBy2p1;
53 uint16_t i, j;
54 float32_t in;
55
56 /* Initializations */
57 j = 0U;
58 fftLenBy2 = fftSize >> 1U;
59 fftLenBy2p1 = (fftSize >> 1U) + 1U;
60
61 /* Bit Reversal Implementation */
62 for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U)
63 {
64 if (i < j)
65 {
66 /* pSrc[i] <-> pSrc[j]; */
67 in = pSrc[2U * i];
68 pSrc[2U * i] = pSrc[2U * j];
69 pSrc[2U * j] = in;
70
71 /* pSrc[i+1U] <-> pSrc[j+1U] */
72 in = pSrc[(2U * i) + 1U];
73 pSrc[(2U * i) + 1U] = pSrc[(2U * j) + 1U];
74 pSrc[(2U * j) + 1U] = in;
75
76 /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
77 in = pSrc[2U * (i + fftLenBy2p1)];
78 pSrc[2U * (i + fftLenBy2p1)] = pSrc[2U * (j + fftLenBy2p1)];
79 pSrc[2U * (j + fftLenBy2p1)] = in;
80
81 /* pSrc[i+fftLenBy2p1+1U] <-> pSrc[j+fftLenBy2p1+1U] */
82 in = pSrc[(2U * (i + fftLenBy2p1)) + 1U];
83 pSrc[(2U * (i + fftLenBy2p1)) + 1U] =
84 pSrc[(2U * (j + fftLenBy2p1)) + 1U];
85 pSrc[(2U * (j + fftLenBy2p1)) + 1U] = in;
86
87 }
88
89 /* pSrc[i+1U] <-> pSrc[j+1U] */
90 in = pSrc[2U * (i + 1U)];
91 pSrc[2U * (i + 1U)] = pSrc[2U * (j + fftLenBy2)];
92 pSrc[2U * (j + fftLenBy2)] = in;
93
94 /* pSrc[i+2U] <-> pSrc[j+2U] */
95 in = pSrc[(2U * (i + 1U)) + 1U];
96 pSrc[(2U * (i + 1U)) + 1U] = pSrc[(2U * (j + fftLenBy2)) + 1U];
97 pSrc[(2U * (j + fftLenBy2)) + 1U] = in;
98
99 /* Reading the index for the bit reversal */
100 j = *pBitRevTab;
101
102 /* Updating the bit reversal index depending on the fft length */
103 pBitRevTab += bitRevFactor;
104 }
105 }
106
107 void arm_bitreversal_q31(
108 q31_t * pSrc,
109 uint32_t fftLen,
110 uint16_t bitRevFactor,
111 const uint16_t * pBitRevTab);
112
113 /**
114 @brief In-place Q31 bit reversal function.
115 @param[in,out] pSrc points to in-place Q31 data buffer.
116 @param[in] fftLen length of FFT.
117 @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
118 @param[in] pBitRevTab points to bit reversal table
119 */
120
arm_bitreversal_q31(q31_t * pSrc,uint32_t fftLen,uint16_t bitRevFactor,const uint16_t * pBitRevTab)121 ARM_DSP_ATTRIBUTE void arm_bitreversal_q31(
122 q31_t * pSrc,
123 uint32_t fftLen,
124 uint16_t bitRevFactor,
125 const uint16_t * pBitRevTab)
126 {
127 uint32_t fftLenBy2, fftLenBy2p1, i, j;
128 q31_t in;
129
130 /* Initializations */
131 j = 0U;
132 fftLenBy2 = fftLen / 2U;
133 fftLenBy2p1 = (fftLen / 2U) + 1U;
134
135 /* Bit Reversal Implementation */
136 for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U)
137 {
138 if (i < j)
139 {
140 /* pSrc[i] <-> pSrc[j]; */
141 in = pSrc[2U * i];
142 pSrc[2U * i] = pSrc[2U * j];
143 pSrc[2U * j] = in;
144
145 /* pSrc[i+1U] <-> pSrc[j+1U] */
146 in = pSrc[(2U * i) + 1U];
147 pSrc[(2U * i) + 1U] = pSrc[(2U * j) + 1U];
148 pSrc[(2U * j) + 1U] = in;
149
150 /* pSrc[i+fftLenBy2p1] <-> pSrc[j+fftLenBy2p1] */
151 in = pSrc[2U * (i + fftLenBy2p1)];
152 pSrc[2U * (i + fftLenBy2p1)] = pSrc[2U * (j + fftLenBy2p1)];
153 pSrc[2U * (j + fftLenBy2p1)] = in;
154
155 /* pSrc[i+fftLenBy2p1+1U] <-> pSrc[j+fftLenBy2p1+1U] */
156 in = pSrc[(2U * (i + fftLenBy2p1)) + 1U];
157 pSrc[(2U * (i + fftLenBy2p1)) + 1U] =
158 pSrc[(2U * (j + fftLenBy2p1)) + 1U];
159 pSrc[(2U * (j + fftLenBy2p1)) + 1U] = in;
160
161 }
162
163 /* pSrc[i+1U] <-> pSrc[j+1U] */
164 in = pSrc[2U * (i + 1U)];
165 pSrc[2U * (i + 1U)] = pSrc[2U * (j + fftLenBy2)];
166 pSrc[2U * (j + fftLenBy2)] = in;
167
168 /* pSrc[i+2U] <-> pSrc[j+2U] */
169 in = pSrc[(2U * (i + 1U)) + 1U];
170 pSrc[(2U * (i + 1U)) + 1U] = pSrc[(2U * (j + fftLenBy2)) + 1U];
171 pSrc[(2U * (j + fftLenBy2)) + 1U] = in;
172
173 /* Reading the index for the bit reversal */
174 j = *pBitRevTab;
175
176 /* Updating the bit reversal index depending on the fft length */
177 pBitRevTab += bitRevFactor;
178 }
179 }
180
181 void arm_bitreversal_q15(
182 q15_t * pSrc16,
183 uint32_t fftLen,
184 uint16_t bitRevFactor,
185 const uint16_t * pBitRevTab);
186
187
188 /**
189 @brief In-place Q15 bit reversal function.
190 @param[in,out] pSrc16 points to in-place Q15 data buffer
191 @param[in] fftLen length of FFT
192 @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table
193 @param[in] pBitRevTab points to bit reversal table
194 */
195
arm_bitreversal_q15(q15_t * pSrc16,uint32_t fftLen,uint16_t bitRevFactor,const uint16_t * pBitRevTab)196 ARM_DSP_ATTRIBUTE void arm_bitreversal_q15(
197 q15_t * pSrc16,
198 uint32_t fftLen,
199 uint16_t bitRevFactor,
200 const uint16_t * pBitRevTab)
201 {
202 q31_t *pSrc = (q31_t *) pSrc16;
203 q31_t in;
204 uint32_t fftLenBy2, fftLenBy2p1;
205 uint32_t i, j;
206
207 /* Initializations */
208 j = 0U;
209 fftLenBy2 = fftLen / 2U;
210 fftLenBy2p1 = (fftLen / 2U) + 1U;
211
212 /* Bit Reversal Implementation */
213 for (i = 0U; i <= (fftLenBy2 - 2U); i += 2U)
214 {
215 if (i < j)
216 {
217 /* pSrc[i] <-> pSrc[j]; */
218 /* pSrc[i+1U] <-> pSrc[j+1U] */
219 in = pSrc[i];
220 pSrc[i] = pSrc[j];
221 pSrc[j] = in;
222
223 /* pSrc[i + fftLenBy2p1] <-> pSrc[j + fftLenBy2p1]; */
224 /* pSrc[i + fftLenBy2p1+1U] <-> pSrc[j + fftLenBy2p1+1U] */
225 in = pSrc[i + fftLenBy2p1];
226 pSrc[i + fftLenBy2p1] = pSrc[j + fftLenBy2p1];
227 pSrc[j + fftLenBy2p1] = in;
228 }
229
230 /* pSrc[i+1U] <-> pSrc[j+fftLenBy2]; */
231 /* pSrc[i+2] <-> pSrc[j+fftLenBy2+1U] */
232 in = pSrc[i + 1U];
233 pSrc[i + 1U] = pSrc[j + fftLenBy2];
234 pSrc[j + fftLenBy2] = in;
235
236 /* Reading the index for the bit reversal */
237 j = *pBitRevTab;
238
239 /* Updating the bit reversal index depending on the fft length */
240 pBitRevTab += bitRevFactor;
241 }
242 }
243