arm_bitreversal.c
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 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 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 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 }