Keyboard firmwares for Atmel AVR and Cortex-M
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

arm_fir_lattice_f32.c 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  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_lattice_f32.c
  9. *
  10. * Description: Processing function for the floating-point FIR Lattice filter.
  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. * @defgroup FIR_Lattice Finite Impulse Response (FIR) Lattice Filters
  46. *
  47. * This set of functions implements Finite Impulse Response (FIR) lattice filters
  48. * for Q15, Q31 and floating-point data types. Lattice filters are used in a
  49. * variety of adaptive filter applications. The filter structure is feedforward and
  50. * the net impulse response is finite length.
  51. * The functions operate on blocks
  52. * of input and output data and each call to the function processes
  53. * <code>blockSize</code> samples through the filter. <code>pSrc</code> and
  54. * <code>pDst</code> point to input and output arrays containing <code>blockSize</code> values.
  55. *
  56. * \par Algorithm:
  57. * \image html FIRLattice.gif "Finite Impulse Response Lattice filter"
  58. * The following difference equation is implemented:
  59. * <pre>
  60. * f0[n] = g0[n] = x[n]
  61. * fm[n] = fm-1[n] + km * gm-1[n-1] for m = 1, 2, ...M
  62. * gm[n] = km * fm-1[n] + gm-1[n-1] for m = 1, 2, ...M
  63. * y[n] = fM[n]
  64. * </pre>
  65. * \par
  66. * <code>pCoeffs</code> points to tha array of reflection coefficients of size <code>numStages</code>.
  67. * Reflection Coefficients are stored in the following order.
  68. * \par
  69. * <pre>
  70. * {k1, k2, ..., kM}
  71. * </pre>
  72. * where M is number of stages
  73. * \par
  74. * <code>pState</code> points to a state array of size <code>numStages</code>.
  75. * The state variables (g values) hold previous inputs and are stored in the following order.
  76. * <pre>
  77. * {g0[n], g1[n], g2[n] ...gM-1[n]}
  78. * </pre>
  79. * The state variables are updated after each block of data is processed; the coefficients are untouched.
  80. * \par Instance Structure
  81. * The coefficients and state variables for a filter are stored together in an instance data structure.
  82. * A separate instance structure must be defined for each filter.
  83. * Coefficient arrays may be shared among several instances while state variable arrays cannot be shared.
  84. * There are separate instance structure declarations for each of the 3 supported data types.
  85. *
  86. * \par Initialization Functions
  87. * There is also an associated initialization function for each data type.
  88. * The initialization function performs the following operations:
  89. * - Sets the values of the internal structure fields.
  90. * - Zeros out the values in the state buffer.
  91. * To do this manually without calling the init function, assign the follow subfields of the instance structure:
  92. * numStages, pCoeffs, pState. Also set all of the values in pState to zero.
  93. *
  94. * \par
  95. * Use of the initialization function is optional.
  96. * However, if the initialization function is used, then the instance structure cannot be placed into a const data section.
  97. * To place an instance structure into a const data section, the instance structure must be manually initialized.
  98. * Set the values in the state buffer to zeros and then manually initialize the instance structure as follows:
  99. * <pre>
  100. *arm_fir_lattice_instance_f32 S = {numStages, pState, pCoeffs};
  101. *arm_fir_lattice_instance_q31 S = {numStages, pState, pCoeffs};
  102. *arm_fir_lattice_instance_q15 S = {numStages, pState, pCoeffs};
  103. * </pre>
  104. * \par
  105. * where <code>numStages</code> is the number of stages in the filter; <code>pState</code> is the address of the state buffer;
  106. * <code>pCoeffs</code> is the address of the coefficient buffer.
  107. * \par Fixed-Point Behavior
  108. * Care must be taken when using the fixed-point versions of the FIR Lattice filter functions.
  109. * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
  110. * Refer to the function specific documentation below for usage guidelines.
  111. */
  112. /**
  113. * @addtogroup FIR_Lattice
  114. * @{
  115. */
  116. /**
  117. * @brief Processing function for the floating-point FIR lattice filter.
  118. * @param[in] *S points to an instance of the floating-point FIR lattice structure.
  119. * @param[in] *pSrc points to the block of input data.
  120. * @param[out] *pDst points to the block of output data
  121. * @param[in] blockSize number of samples to process.
  122. * @return none.
  123. */
  124. void arm_fir_lattice_f32(
  125. const arm_fir_lattice_instance_f32 * S,
  126. float32_t * pSrc,
  127. float32_t * pDst,
  128. uint32_t blockSize)
  129. {
  130. float32_t *pState; /* State pointer */
  131. float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
  132. float32_t *px; /* temporary state pointer */
  133. float32_t *pk; /* temporary coefficient pointer */
  134. #ifndef ARM_MATH_CM0_FAMILY
  135. /* Run the below code for Cortex-M4 and Cortex-M3 */
  136. float32_t fcurr1, fnext1, gcurr1, gnext1; /* temporary variables for first sample in loop unrolling */
  137. float32_t fcurr2, fnext2, gnext2; /* temporary variables for second sample in loop unrolling */
  138. float32_t fcurr3, fnext3, gnext3; /* temporary variables for third sample in loop unrolling */
  139. float32_t fcurr4, fnext4, gnext4; /* temporary variables for fourth sample in loop unrolling */
  140. uint32_t numStages = S->numStages; /* Number of stages in the filter */
  141. uint32_t blkCnt, stageCnt; /* temporary variables for counts */
  142. gcurr1 = 0.0f;
  143. pState = &S->pState[0];
  144. blkCnt = blockSize >> 2;
  145. /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
  146. a second loop below computes the remaining 1 to 3 samples. */
  147. while(blkCnt > 0u)
  148. {
  149. /* Read two samples from input buffer */
  150. /* f0(n) = x(n) */
  151. fcurr1 = *pSrc++;
  152. fcurr2 = *pSrc++;
  153. /* Initialize coeff pointer */
  154. pk = (pCoeffs);
  155. /* Initialize state pointer */
  156. px = pState;
  157. /* Read g0(n-1) from state */
  158. gcurr1 = *px;
  159. /* Process first sample for first tap */
  160. /* f1(n) = f0(n) + K1 * g0(n-1) */
  161. fnext1 = fcurr1 + ((*pk) * gcurr1);
  162. /* g1(n) = f0(n) * K1 + g0(n-1) */
  163. gnext1 = (fcurr1 * (*pk)) + gcurr1;
  164. /* Process second sample for first tap */
  165. /* for sample 2 processing */
  166. fnext2 = fcurr2 + ((*pk) * fcurr1);
  167. gnext2 = (fcurr2 * (*pk)) + fcurr1;
  168. /* Read next two samples from input buffer */
  169. /* f0(n+2) = x(n+2) */
  170. fcurr3 = *pSrc++;
  171. fcurr4 = *pSrc++;
  172. /* Copy only last input samples into the state buffer
  173. which will be used for next four samples processing */
  174. *px++ = fcurr4;
  175. /* Process third sample for first tap */
  176. fnext3 = fcurr3 + ((*pk) * fcurr2);
  177. gnext3 = (fcurr3 * (*pk)) + fcurr2;
  178. /* Process fourth sample for first tap */
  179. fnext4 = fcurr4 + ((*pk) * fcurr3);
  180. gnext4 = (fcurr4 * (*pk++)) + fcurr3;
  181. /* Update of f values for next coefficient set processing */
  182. fcurr1 = fnext1;
  183. fcurr2 = fnext2;
  184. fcurr3 = fnext3;
  185. fcurr4 = fnext4;
  186. /* Loop unrolling. Process 4 taps at a time . */
  187. stageCnt = (numStages - 1u) >> 2u;
  188. /* Loop over the number of taps. Unroll by a factor of 4.
  189. ** Repeat until we've computed numStages-3 coefficients. */
  190. /* Process 2nd, 3rd, 4th and 5th taps ... here */
  191. while(stageCnt > 0u)
  192. {
  193. /* Read g1(n-1), g3(n-1) .... from state */
  194. gcurr1 = *px;
  195. /* save g1(n) in state buffer */
  196. *px++ = gnext4;
  197. /* Process first sample for 2nd, 6th .. tap */
  198. /* Sample processing for K2, K6.... */
  199. /* f2(n) = f1(n) + K2 * g1(n-1) */
  200. fnext1 = fcurr1 + ((*pk) * gcurr1);
  201. /* Process second sample for 2nd, 6th .. tap */
  202. /* for sample 2 processing */
  203. fnext2 = fcurr2 + ((*pk) * gnext1);
  204. /* Process third sample for 2nd, 6th .. tap */
  205. fnext3 = fcurr3 + ((*pk) * gnext2);
  206. /* Process fourth sample for 2nd, 6th .. tap */
  207. fnext4 = fcurr4 + ((*pk) * gnext3);
  208. /* g2(n) = f1(n) * K2 + g1(n-1) */
  209. /* Calculation of state values for next stage */
  210. gnext4 = (fcurr4 * (*pk)) + gnext3;
  211. gnext3 = (fcurr3 * (*pk)) + gnext2;
  212. gnext2 = (fcurr2 * (*pk)) + gnext1;
  213. gnext1 = (fcurr1 * (*pk++)) + gcurr1;
  214. /* Read g2(n-1), g4(n-1) .... from state */
  215. gcurr1 = *px;
  216. /* save g2(n) in state buffer */
  217. *px++ = gnext4;
  218. /* Sample processing for K3, K7.... */
  219. /* Process first sample for 3rd, 7th .. tap */
  220. /* f3(n) = f2(n) + K3 * g2(n-1) */
  221. fcurr1 = fnext1 + ((*pk) * gcurr1);
  222. /* Process second sample for 3rd, 7th .. tap */
  223. fcurr2 = fnext2 + ((*pk) * gnext1);
  224. /* Process third sample for 3rd, 7th .. tap */
  225. fcurr3 = fnext3 + ((*pk) * gnext2);
  226. /* Process fourth sample for 3rd, 7th .. tap */
  227. fcurr4 = fnext4 + ((*pk) * gnext3);
  228. /* Calculation of state values for next stage */
  229. /* g3(n) = f2(n) * K3 + g2(n-1) */
  230. gnext4 = (fnext4 * (*pk)) + gnext3;
  231. gnext3 = (fnext3 * (*pk)) + gnext2;
  232. gnext2 = (fnext2 * (*pk)) + gnext1;
  233. gnext1 = (fnext1 * (*pk++)) + gcurr1;
  234. /* Read g1(n-1), g3(n-1) .... from state */
  235. gcurr1 = *px;
  236. /* save g3(n) in state buffer */
  237. *px++ = gnext4;
  238. /* Sample processing for K4, K8.... */
  239. /* Process first sample for 4th, 8th .. tap */
  240. /* f4(n) = f3(n) + K4 * g3(n-1) */
  241. fnext1 = fcurr1 + ((*pk) * gcurr1);
  242. /* Process second sample for 4th, 8th .. tap */
  243. /* for sample 2 processing */
  244. fnext2 = fcurr2 + ((*pk) * gnext1);
  245. /* Process third sample for 4th, 8th .. tap */
  246. fnext3 = fcurr3 + ((*pk) * gnext2);
  247. /* Process fourth sample for 4th, 8th .. tap */
  248. fnext4 = fcurr4 + ((*pk) * gnext3);
  249. /* g4(n) = f3(n) * K4 + g3(n-1) */
  250. /* Calculation of state values for next stage */
  251. gnext4 = (fcurr4 * (*pk)) + gnext3;
  252. gnext3 = (fcurr3 * (*pk)) + gnext2;
  253. gnext2 = (fcurr2 * (*pk)) + gnext1;
  254. gnext1 = (fcurr1 * (*pk++)) + gcurr1;
  255. /* Read g2(n-1), g4(n-1) .... from state */
  256. gcurr1 = *px;
  257. /* save g4(n) in state buffer */
  258. *px++ = gnext4;
  259. /* Sample processing for K5, K9.... */
  260. /* Process first sample for 5th, 9th .. tap */
  261. /* f5(n) = f4(n) + K5 * g4(n-1) */
  262. fcurr1 = fnext1 + ((*pk) * gcurr1);
  263. /* Process second sample for 5th, 9th .. tap */
  264. fcurr2 = fnext2 + ((*pk) * gnext1);
  265. /* Process third sample for 5th, 9th .. tap */
  266. fcurr3 = fnext3 + ((*pk) * gnext2);
  267. /* Process fourth sample for 5th, 9th .. tap */
  268. fcurr4 = fnext4 + ((*pk) * gnext3);
  269. /* Calculation of state values for next stage */
  270. /* g5(n) = f4(n) * K5 + g4(n-1) */
  271. gnext4 = (fnext4 * (*pk)) + gnext3;
  272. gnext3 = (fnext3 * (*pk)) + gnext2;
  273. gnext2 = (fnext2 * (*pk)) + gnext1;
  274. gnext1 = (fnext1 * (*pk++)) + gcurr1;
  275. stageCnt--;
  276. }
  277. /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */
  278. stageCnt = (numStages - 1u) % 0x4u;
  279. while(stageCnt > 0u)
  280. {
  281. gcurr1 = *px;
  282. /* save g value in state buffer */
  283. *px++ = gnext4;
  284. /* Process four samples for last three taps here */
  285. fnext1 = fcurr1 + ((*pk) * gcurr1);
  286. fnext2 = fcurr2 + ((*pk) * gnext1);
  287. fnext3 = fcurr3 + ((*pk) * gnext2);
  288. fnext4 = fcurr4 + ((*pk) * gnext3);
  289. /* g1(n) = f0(n) * K1 + g0(n-1) */
  290. gnext4 = (fcurr4 * (*pk)) + gnext3;
  291. gnext3 = (fcurr3 * (*pk)) + gnext2;
  292. gnext2 = (fcurr2 * (*pk)) + gnext1;
  293. gnext1 = (fcurr1 * (*pk++)) + gcurr1;
  294. /* Update of f values for next coefficient set processing */
  295. fcurr1 = fnext1;
  296. fcurr2 = fnext2;
  297. fcurr3 = fnext3;
  298. fcurr4 = fnext4;
  299. stageCnt--;
  300. }
  301. /* The results in the 4 accumulators, store in the destination buffer. */
  302. /* y(n) = fN(n) */
  303. *pDst++ = fcurr1;
  304. *pDst++ = fcurr2;
  305. *pDst++ = fcurr3;
  306. *pDst++ = fcurr4;
  307. blkCnt--;
  308. }
  309. /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
  310. ** No loop unrolling is used. */
  311. blkCnt = blockSize % 0x4u;
  312. while(blkCnt > 0u)
  313. {
  314. /* f0(n) = x(n) */
  315. fcurr1 = *pSrc++;
  316. /* Initialize coeff pointer */
  317. pk = (pCoeffs);
  318. /* Initialize state pointer */
  319. px = pState;
  320. /* read g2(n) from state buffer */
  321. gcurr1 = *px;
  322. /* for sample 1 processing */
  323. /* f1(n) = f0(n) + K1 * g0(n-1) */
  324. fnext1 = fcurr1 + ((*pk) * gcurr1);
  325. /* g1(n) = f0(n) * K1 + g0(n-1) */
  326. gnext1 = (fcurr1 * (*pk++)) + gcurr1;
  327. /* save g1(n) in state buffer */
  328. *px++ = fcurr1;
  329. /* f1(n) is saved in fcurr1
  330. for next stage processing */
  331. fcurr1 = fnext1;
  332. stageCnt = (numStages - 1u);
  333. /* stage loop */
  334. while(stageCnt > 0u)
  335. {
  336. /* read g2(n) from state buffer */
  337. gcurr1 = *px;
  338. /* save g1(n) in state buffer */
  339. *px++ = gnext1;
  340. /* Sample processing for K2, K3.... */
  341. /* f2(n) = f1(n) + K2 * g1(n-1) */
  342. fnext1 = fcurr1 + ((*pk) * gcurr1);
  343. /* g2(n) = f1(n) * K2 + g1(n-1) */
  344. gnext1 = (fcurr1 * (*pk++)) + gcurr1;
  345. /* f1(n) is saved in fcurr1
  346. for next stage processing */
  347. fcurr1 = fnext1;
  348. stageCnt--;
  349. }
  350. /* y(n) = fN(n) */
  351. *pDst++ = fcurr1;
  352. blkCnt--;
  353. }
  354. #else
  355. /* Run the below code for Cortex-M0 */
  356. float32_t fcurr, fnext, gcurr, gnext; /* temporary variables */
  357. uint32_t numStages = S->numStages; /* Length of the filter */
  358. uint32_t blkCnt, stageCnt; /* temporary variables for counts */
  359. pState = &S->pState[0];
  360. blkCnt = blockSize;
  361. while(blkCnt > 0u)
  362. {
  363. /* f0(n) = x(n) */
  364. fcurr = *pSrc++;
  365. /* Initialize coeff pointer */
  366. pk = pCoeffs;
  367. /* Initialize state pointer */
  368. px = pState;
  369. /* read g0(n-1) from state buffer */
  370. gcurr = *px;
  371. /* for sample 1 processing */
  372. /* f1(n) = f0(n) + K1 * g0(n-1) */
  373. fnext = fcurr + ((*pk) * gcurr);
  374. /* g1(n) = f0(n) * K1 + g0(n-1) */
  375. gnext = (fcurr * (*pk++)) + gcurr;
  376. /* save f0(n) in state buffer */
  377. *px++ = fcurr;
  378. /* f1(n) is saved in fcurr
  379. for next stage processing */
  380. fcurr = fnext;
  381. stageCnt = (numStages - 1u);
  382. /* stage loop */
  383. while(stageCnt > 0u)
  384. {
  385. /* read g2(n) from state buffer */
  386. gcurr = *px;
  387. /* save g1(n) in state buffer */
  388. *px++ = gnext;
  389. /* Sample processing for K2, K3.... */
  390. /* f2(n) = f1(n) + K2 * g1(n-1) */
  391. fnext = fcurr + ((*pk) * gcurr);
  392. /* g2(n) = f1(n) * K2 + g1(n-1) */
  393. gnext = (fcurr * (*pk++)) + gcurr;
  394. /* f1(n) is saved in fcurr1
  395. for next stage processing */
  396. fcurr = fnext;
  397. stageCnt--;
  398. }
  399. /* y(n) = fN(n) */
  400. *pDst++ = fcurr;
  401. blkCnt--;
  402. }
  403. #endif /* #ifndef ARM_MATH_CM0_FAMILY */
  404. }
  405. /**
  406. * @} end of FIR_Lattice group
  407. */