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