Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

arm_fir_decimate_q15.c 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010-2013 ARM Limited. All rights reserved.
  3. *
  4. * $Date: 17. January 2013
  5. * $Revision: V1.4.1
  6. *
  7. * Project: CMSIS DSP Library
  8. * Title: arm_fir_decimate_q15.c
  9. *
  10. * Description: Q15 FIR Decimator.
  11. *
  12. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. * - Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in
  21. * the documentation and/or other materials provided with the
  22. * distribution.
  23. * - Neither the name of ARM LIMITED nor the names of its contributors
  24. * may be used to endorse or promote products derived from this
  25. * software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.
  39. * -------------------------------------------------------------------- */
  40. #include "arm_math.h"
  41. /**
  42. * @ingroup groupFilters
  43. */
  44. /**
  45. * @addtogroup FIR_decimate
  46. * @{
  47. */
  48. /**
  49. * @brief Processing function for the Q15 FIR decimator.
  50. * @param[in] *S points to an instance of the Q15 FIR decimator structure.
  51. * @param[in] *pSrc points to the block of input data.
  52. * @param[out] *pDst points to the location where the output result is written.
  53. * @param[in] blockSize number of input samples to process per call.
  54. * @return none.
  55. *
  56. * <b>Scaling and Overflow Behavior:</b>
  57. * \par
  58. * The function is implemented using a 64-bit internal accumulator.
  59. * Both coefficients and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
  60. * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
  61. * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
  62. * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
  63. * Lastly, the accumulator is saturated to yield a result in 1.15 format.
  64. *
  65. * \par
  66. * Refer to the function <code>arm_fir_decimate_fast_q15()</code> for a faster but less precise implementation of this function for Cortex-M3 and Cortex-M4.
  67. */
  68. #ifndef ARM_MATH_CM0_FAMILY
  69. #ifndef UNALIGNED_SUPPORT_DISABLE
  70. void arm_fir_decimate_q15(
  71. const arm_fir_decimate_instance_q15 * S,
  72. q15_t * pSrc,
  73. q15_t * pDst,
  74. uint32_t blockSize)
  75. {
  76. q15_t *pState = S->pState; /* State pointer */
  77. q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
  78. q15_t *pStateCurnt; /* Points to the current sample of the state */
  79. q15_t *px; /* Temporary pointer for state buffer */
  80. q15_t *pb; /* Temporary pointer coefficient buffer */
  81. q31_t x0, x1, c0, c1; /* Temporary variables to hold state and coefficient values */
  82. q63_t sum0; /* Accumulators */
  83. q63_t acc0, acc1;
  84. q15_t *px0, *px1;
  85. uint32_t blkCntN3;
  86. uint32_t numTaps = S->numTaps; /* Number of taps */
  87. uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */
  88. /* S->pState buffer contains previous frame (numTaps - 1) samples */
  89. /* pStateCurnt points to the location where the new input data should be written */
  90. pStateCurnt = S->pState + (numTaps - 1u);
  91. /* Total number of output samples to be computed */
  92. blkCnt = outBlockSize / 2;
  93. blkCntN3 = outBlockSize - (2 * blkCnt);
  94. while(blkCnt > 0u)
  95. {
  96. /* Copy decimation factor number of new input samples into the state buffer */
  97. i = 2 * S->M;
  98. do
  99. {
  100. *pStateCurnt++ = *pSrc++;
  101. } while(--i);
  102. /* Set accumulator to zero */
  103. acc0 = 0;
  104. acc1 = 0;
  105. /* Initialize state pointer */
  106. px0 = pState;
  107. px1 = pState + S->M;
  108. /* Initialize coeff pointer */
  109. pb = pCoeffs;
  110. /* Loop unrolling. Process 4 taps at a time. */
  111. tapCnt = numTaps >> 2;
  112. /* Loop over the number of taps. Unroll by a factor of 4.
  113. ** Repeat until we've computed numTaps-4 coefficients. */
  114. while(tapCnt > 0u)
  115. {
  116. /* Read the Read b[numTaps-1] and b[numTaps-2] coefficients */
  117. c0 = *__SIMD32(pb)++;
  118. /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */
  119. x0 = *__SIMD32(px0)++;
  120. x1 = *__SIMD32(px1)++;
  121. /* Perform the multiply-accumulate */
  122. acc0 = __SMLALD(x0, c0, acc0);
  123. acc1 = __SMLALD(x1, c0, acc1);
  124. /* Read the b[numTaps-3] and b[numTaps-4] coefficient */
  125. c0 = *__SIMD32(pb)++;
  126. /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */
  127. x0 = *__SIMD32(px0)++;
  128. x1 = *__SIMD32(px1)++;
  129. /* Perform the multiply-accumulate */
  130. acc0 = __SMLALD(x0, c0, acc0);
  131. acc1 = __SMLALD(x1, c0, acc1);
  132. /* Decrement the loop counter */
  133. tapCnt--;
  134. }
  135. /* If the filter length is not a multiple of 4, compute the remaining filter taps */
  136. tapCnt = numTaps % 0x4u;
  137. while(tapCnt > 0u)
  138. {
  139. /* Read coefficients */
  140. c0 = *pb++;
  141. /* Fetch 1 state variable */
  142. x0 = *px0++;
  143. x1 = *px1++;
  144. /* Perform the multiply-accumulate */
  145. acc0 = __SMLALD(x0, c0, acc0);
  146. acc1 = __SMLALD(x1, c0, acc1);
  147. /* Decrement the loop counter */
  148. tapCnt--;
  149. }
  150. /* Advance the state pointer by the decimation factor
  151. * to process the next group of decimation factor number samples */
  152. pState = pState + S->M * 2;
  153. /* Store filter output, smlad returns the values in 2.14 format */
  154. /* so downsacle by 15 to get output in 1.15 */
  155. *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16));
  156. *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16));
  157. /* Decrement the loop counter */
  158. blkCnt--;
  159. }
  160. while(blkCntN3 > 0u)
  161. {
  162. /* Copy decimation factor number of new input samples into the state buffer */
  163. i = S->M;
  164. do
  165. {
  166. *pStateCurnt++ = *pSrc++;
  167. } while(--i);
  168. /*Set sum to zero */
  169. sum0 = 0;
  170. /* Initialize state pointer */
  171. px = pState;
  172. /* Initialize coeff pointer */
  173. pb = pCoeffs;
  174. /* Loop unrolling. Process 4 taps at a time. */
  175. tapCnt = numTaps >> 2;
  176. /* Loop over the number of taps. Unroll by a factor of 4.
  177. ** Repeat until we've computed numTaps-4 coefficients. */
  178. while(tapCnt > 0u)
  179. {
  180. /* Read the Read b[numTaps-1] and b[numTaps-2] coefficients */
  181. c0 = *__SIMD32(pb)++;
  182. /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */
  183. x0 = *__SIMD32(px)++;
  184. /* Read the b[numTaps-3] and b[numTaps-4] coefficient */
  185. c1 = *__SIMD32(pb)++;
  186. /* Perform the multiply-accumulate */
  187. sum0 = __SMLALD(x0, c0, sum0);
  188. /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */
  189. x0 = *__SIMD32(px)++;
  190. /* Perform the multiply-accumulate */
  191. sum0 = __SMLALD(x0, c1, sum0);
  192. /* Decrement the loop counter */
  193. tapCnt--;
  194. }
  195. /* If the filter length is not a multiple of 4, compute the remaining filter taps */
  196. tapCnt = numTaps % 0x4u;
  197. while(tapCnt > 0u)
  198. {
  199. /* Read coefficients */
  200. c0 = *pb++;
  201. /* Fetch 1 state variable */
  202. x0 = *px++;
  203. /* Perform the multiply-accumulate */
  204. sum0 = __SMLALD(x0, c0, sum0);
  205. /* Decrement the loop counter */
  206. tapCnt--;
  207. }
  208. /* Advance the state pointer by the decimation factor
  209. * to process the next group of decimation factor number samples */
  210. pState = pState + S->M;
  211. /* Store filter output, smlad returns the values in 2.14 format */
  212. /* so downsacle by 15 to get output in 1.15 */
  213. *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16));
  214. /* Decrement the loop counter */
  215. blkCntN3--;
  216. }
  217. /* Processing is complete.
  218. ** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
  219. ** This prepares the state buffer for the next function call. */
  220. /* Points to the start of the state buffer */
  221. pStateCurnt = S->pState;
  222. i = (numTaps - 1u) >> 2u;
  223. /* copy data */
  224. while(i > 0u)
  225. {
  226. *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
  227. *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
  228. /* Decrement the loop counter */
  229. i--;
  230. }
  231. i = (numTaps - 1u) % 0x04u;
  232. /* copy data */
  233. while(i > 0u)
  234. {
  235. *pStateCurnt++ = *pState++;
  236. /* Decrement the loop counter */
  237. i--;
  238. }
  239. }
  240. #else
  241. void arm_fir_decimate_q15(
  242. const arm_fir_decimate_instance_q15 * S,
  243. q15_t * pSrc,
  244. q15_t * pDst,
  245. uint32_t blockSize)
  246. {
  247. q15_t *pState = S->pState; /* State pointer */
  248. q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
  249. q15_t *pStateCurnt; /* Points to the current sample of the state */
  250. q15_t *px; /* Temporary pointer for state buffer */
  251. q15_t *pb; /* Temporary pointer coefficient buffer */
  252. q15_t x0, x1, c0; /* Temporary variables to hold state and coefficient values */
  253. q63_t sum0; /* Accumulators */
  254. q63_t acc0, acc1;
  255. q15_t *px0, *px1;
  256. uint32_t blkCntN3;
  257. uint32_t numTaps = S->numTaps; /* Number of taps */
  258. uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */
  259. /* S->pState buffer contains previous frame (numTaps - 1) samples */
  260. /* pStateCurnt points to the location where the new input data should be written */
  261. pStateCurnt = S->pState + (numTaps - 1u);
  262. /* Total number of output samples to be computed */
  263. blkCnt = outBlockSize / 2;
  264. blkCntN3 = outBlockSize - (2 * blkCnt);
  265. while(blkCnt > 0u)
  266. {
  267. /* Copy decimation factor number of new input samples into the state buffer */
  268. i = 2 * S->M;
  269. do
  270. {
  271. *pStateCurnt++ = *pSrc++;
  272. } while(--i);
  273. /* Set accumulator to zero */
  274. acc0 = 0;
  275. acc1 = 0;
  276. /* Initialize state pointer */
  277. px0 = pState;
  278. px1 = pState + S->M;
  279. /* Initialize coeff pointer */
  280. pb = pCoeffs;
  281. /* Loop unrolling. Process 4 taps at a time. */
  282. tapCnt = numTaps >> 2;
  283. /* Loop over the number of taps. Unroll by a factor of 4.
  284. ** Repeat until we've computed numTaps-4 coefficients. */
  285. while(tapCnt > 0u)
  286. {
  287. /* Read the Read b[numTaps-1] coefficients */
  288. c0 = *pb++;
  289. /* Read x[n-numTaps-1] for sample 0 and for sample 1 */
  290. x0 = *px0++;
  291. x1 = *px1++;
  292. /* Perform the multiply-accumulate */
  293. acc0 += x0 * c0;
  294. acc1 += x1 * c0;
  295. /* Read the b[numTaps-2] coefficient */
  296. c0 = *pb++;
  297. /* Read x[n-numTaps-2] for sample 0 and sample 1 */
  298. x0 = *px0++;
  299. x1 = *px1++;
  300. /* Perform the multiply-accumulate */
  301. acc0 += x0 * c0;
  302. acc1 += x1 * c0;
  303. /* Read the b[numTaps-3] coefficients */
  304. c0 = *pb++;
  305. /* Read x[n-numTaps-3] for sample 0 and sample 1 */
  306. x0 = *px0++;
  307. x1 = *px1++;
  308. /* Perform the multiply-accumulate */
  309. acc0 += x0 * c0;
  310. acc1 += x1 * c0;
  311. /* Read the b[numTaps-4] coefficient */
  312. c0 = *pb++;
  313. /* Read x[n-numTaps-4] for sample 0 and sample 1 */
  314. x0 = *px0++;
  315. x1 = *px1++;
  316. /* Perform the multiply-accumulate */
  317. acc0 += x0 * c0;
  318. acc1 += x1 * c0;
  319. /* Decrement the loop counter */
  320. tapCnt--;
  321. }
  322. /* If the filter length is not a multiple of 4, compute the remaining filter taps */
  323. tapCnt = numTaps % 0x4u;
  324. while(tapCnt > 0u)
  325. {
  326. /* Read coefficients */
  327. c0 = *pb++;
  328. /* Fetch 1 state variable */
  329. x0 = *px0++;
  330. x1 = *px1++;
  331. /* Perform the multiply-accumulate */
  332. acc0 += x0 * c0;
  333. acc1 += x1 * c0;
  334. /* Decrement the loop counter */
  335. tapCnt--;
  336. }
  337. /* Advance the state pointer by the decimation factor
  338. * to process the next group of decimation factor number samples */
  339. pState = pState + S->M * 2;
  340. /* Store filter output, smlad returns the values in 2.14 format */
  341. /* so downsacle by 15 to get output in 1.15 */
  342. *pDst++ = (q15_t) (__SSAT((acc0 >> 15), 16));
  343. *pDst++ = (q15_t) (__SSAT((acc1 >> 15), 16));
  344. /* Decrement the loop counter */
  345. blkCnt--;
  346. }
  347. while(blkCntN3 > 0u)
  348. {
  349. /* Copy decimation factor number of new input samples into the state buffer */
  350. i = S->M;
  351. do
  352. {
  353. *pStateCurnt++ = *pSrc++;
  354. } while(--i);
  355. /*Set sum to zero */
  356. sum0 = 0;
  357. /* Initialize state pointer */
  358. px = pState;
  359. /* Initialize coeff pointer */
  360. pb = pCoeffs;
  361. /* Loop unrolling. Process 4 taps at a time. */
  362. tapCnt = numTaps >> 2;
  363. /* Loop over the number of taps. Unroll by a factor of 4.
  364. ** Repeat until we've computed numTaps-4 coefficients. */
  365. while(tapCnt > 0u)
  366. {
  367. /* Read the Read b[numTaps-1] coefficients */
  368. c0 = *pb++;
  369. /* Read x[n-numTaps-1] and sample */
  370. x0 = *px++;
  371. /* Perform the multiply-accumulate */
  372. sum0 += x0 * c0;
  373. /* Read the b[numTaps-2] coefficient */
  374. c0 = *pb++;
  375. /* Read x[n-numTaps-2] and sample */
  376. x0 = *px++;
  377. /* Perform the multiply-accumulate */
  378. sum0 += x0 * c0;
  379. /* Read the b[numTaps-3] coefficients */
  380. c0 = *pb++;
  381. /* Read x[n-numTaps-3] sample */
  382. x0 = *px++;
  383. /* Perform the multiply-accumulate */
  384. sum0 += x0 * c0;
  385. /* Read the b[numTaps-4] coefficient */
  386. c0 = *pb++;
  387. /* Read x[n-numTaps-4] sample */
  388. x0 = *px++;
  389. /* Perform the multiply-accumulate */
  390. sum0 += x0 * c0;
  391. /* Decrement the loop counter */
  392. tapCnt--;
  393. }
  394. /* If the filter length is not a multiple of 4, compute the remaining filter taps */
  395. tapCnt = numTaps % 0x4u;
  396. while(tapCnt > 0u)
  397. {
  398. /* Read coefficients */
  399. c0 = *pb++;
  400. /* Fetch 1 state variable */
  401. x0 = *px++;
  402. /* Perform the multiply-accumulate */
  403. sum0 += x0 * c0;
  404. /* Decrement the loop counter */
  405. tapCnt--;
  406. }
  407. /* Advance the state pointer by the decimation factor
  408. * to process the next group of decimation factor number samples */
  409. pState = pState + S->M;
  410. /* Store filter output, smlad returns the values in 2.14 format */
  411. /* so downsacle by 15 to get output in 1.15 */
  412. *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16));
  413. /* Decrement the loop counter */
  414. blkCntN3--;
  415. }
  416. /* Processing is complete.
  417. ** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
  418. ** This prepares the state buffer for the next function call. */
  419. /* Points to the start of the state buffer */
  420. pStateCurnt = S->pState;
  421. i = (numTaps - 1u) >> 2u;
  422. /* copy data */
  423. while(i > 0u)
  424. {
  425. *pStateCurnt++ = *pState++;
  426. *pStateCurnt++ = *pState++;
  427. *pStateCurnt++ = *pState++;
  428. *pStateCurnt++ = *pState++;
  429. /* Decrement the loop counter */
  430. i--;
  431. }
  432. i = (numTaps - 1u) % 0x04u;
  433. /* copy data */
  434. while(i > 0u)
  435. {
  436. *pStateCurnt++ = *pState++;
  437. /* Decrement the loop counter */
  438. i--;
  439. }
  440. }
  441. #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
  442. #else
  443. void arm_fir_decimate_q15(
  444. const arm_fir_decimate_instance_q15 * S,
  445. q15_t * pSrc,
  446. q15_t * pDst,
  447. uint32_t blockSize)
  448. {
  449. q15_t *pState = S->pState; /* State pointer */
  450. q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
  451. q15_t *pStateCurnt; /* Points to the current sample of the state */
  452. q15_t *px; /* Temporary pointer for state buffer */
  453. q15_t *pb; /* Temporary pointer coefficient buffer */
  454. q31_t x0, c0; /* Temporary variables to hold state and coefficient values */
  455. q63_t sum0; /* Accumulators */
  456. uint32_t numTaps = S->numTaps; /* Number of taps */
  457. uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */
  458. /* Run the below code for Cortex-M0 */
  459. /* S->pState buffer contains previous frame (numTaps - 1) samples */
  460. /* pStateCurnt points to the location where the new input data should be written */
  461. pStateCurnt = S->pState + (numTaps - 1u);
  462. /* Total number of output samples to be computed */
  463. blkCnt = outBlockSize;
  464. while(blkCnt > 0u)
  465. {
  466. /* Copy decimation factor number of new input samples into the state buffer */
  467. i = S->M;
  468. do
  469. {
  470. *pStateCurnt++ = *pSrc++;
  471. } while(--i);
  472. /*Set sum to zero */
  473. sum0 = 0;
  474. /* Initialize state pointer */
  475. px = pState;
  476. /* Initialize coeff pointer */
  477. pb = pCoeffs;
  478. tapCnt = numTaps;
  479. while(tapCnt > 0u)
  480. {
  481. /* Read coefficients */
  482. c0 = *pb++;
  483. /* Fetch 1 state variable */
  484. x0 = *px++;
  485. /* Perform the multiply-accumulate */
  486. sum0 += (q31_t) x0 *c0;
  487. /* Decrement the loop counter */
  488. tapCnt--;
  489. }
  490. /* Advance the state pointer by the decimation factor
  491. * to process the next group of decimation factor number samples */
  492. pState = pState + S->M;
  493. /*Store filter output , smlad will return the values in 2.14 format */
  494. /* so downsacle by 15 to get output in 1.15 */
  495. *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16));
  496. /* Decrement the loop counter */
  497. blkCnt--;
  498. }
  499. /* Processing is complete.
  500. ** Now copy the last numTaps - 1 samples to the start of the state buffer.
  501. ** This prepares the state buffer for the next function call. */
  502. /* Points to the start of the state buffer */
  503. pStateCurnt = S->pState;
  504. i = numTaps - 1u;
  505. /* copy data */
  506. while(i > 0u)
  507. {
  508. *pStateCurnt++ = *pState++;
  509. /* Decrement the loop counter */
  510. i--;
  511. }
  512. }
  513. #endif /* #ifndef ARM_MATH_CM0_FAMILY */
  514. /**
  515. * @} end of FIR_decimate group
  516. */