STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
arm_lms_f32.c
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------
2 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.
3 *
4 * $Date: 19. March 2015
5 * $Revision: V.1.4.5
6 *
7 * Project: CMSIS DSP Library
8 * Title: arm_lms_f32.c
9 *
10 * Description: Processing function for the floating-point LMS 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 
41 #include "arm_math.h"
42 
182  const arm_lms_instance_f32 * S,
183  float32_t * pSrc,
184  float32_t * pRef,
185  float32_t * pOut,
186  float32_t * pErr,
187  uint32_t blockSize)
188 {
189  float32_t *pState = S->pState; /* State pointer */
190  float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
191  float32_t *pStateCurnt; /* Points to the current sample of the state */
192  float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */
193  float32_t mu = S->mu; /* Adaptive factor */
194  uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */
195  uint32_t tapCnt, blkCnt; /* Loop counters */
196  float32_t sum, e, d; /* accumulator, error, reference data sample */
197  float32_t w = 0.0f; /* weight factor */
198 
199  e = 0.0f;
200  d = 0.0f;
201 
202  /* S->pState points to state array which contains previous frame (numTaps - 1) samples */
203  /* pStateCurnt points to the location where the new input data should be written */
204  pStateCurnt = &(S->pState[(numTaps - 1u)]);
205 
206  blkCnt = blockSize;
207 
208 
209 #ifndef ARM_MATH_CM0_FAMILY
210 
211  /* Run the below code for Cortex-M4 and Cortex-M3 */
212 
213  while(blkCnt > 0u)
214  {
215  /* Copy the new input sample into the state buffer */
216  *pStateCurnt++ = *pSrc++;
217 
218  /* Initialize pState pointer */
219  px = pState;
220 
221  /* Initialize coeff pointer */
222  pb = (pCoeffs);
223 
224  /* Set the accumulator to zero */
225  sum = 0.0f;
226 
227  /* Loop unrolling. Process 4 taps at a time. */
228  tapCnt = numTaps >> 2;
229 
230  while(tapCnt > 0u)
231  {
232  /* Perform the multiply-accumulate */
233  sum += (*px++) * (*pb++);
234  sum += (*px++) * (*pb++);
235  sum += (*px++) * (*pb++);
236  sum += (*px++) * (*pb++);
237 
238  /* Decrement the loop counter */
239  tapCnt--;
240  }
241 
242  /* If the filter length is not a multiple of 4, compute the remaining filter taps */
243  tapCnt = numTaps % 0x4u;
244 
245  while(tapCnt > 0u)
246  {
247  /* Perform the multiply-accumulate */
248  sum += (*px++) * (*pb++);
249 
250  /* Decrement the loop counter */
251  tapCnt--;
252  }
253 
254  /* The result in the accumulator, store in the destination buffer. */
255  *pOut++ = sum;
256 
257  /* Compute and store error */
258  d = (float32_t) (*pRef++);
259  e = d - sum;
260  *pErr++ = e;
261 
262  /* Calculation of Weighting factor for the updating filter coefficients */
263  w = e * mu;
264 
265  /* Initialize pState pointer */
266  px = pState;
267 
268  /* Initialize coeff pointer */
269  pb = (pCoeffs);
270 
271  /* Loop unrolling. Process 4 taps at a time. */
272  tapCnt = numTaps >> 2;
273 
274  /* Update filter coefficients */
275  while(tapCnt > 0u)
276  {
277  /* Perform the multiply-accumulate */
278  *pb = *pb + (w * (*px++));
279  pb++;
280 
281  *pb = *pb + (w * (*px++));
282  pb++;
283 
284  *pb = *pb + (w * (*px++));
285  pb++;
286 
287  *pb = *pb + (w * (*px++));
288  pb++;
289 
290  /* Decrement the loop counter */
291  tapCnt--;
292  }
293 
294  /* If the filter length is not a multiple of 4, compute the remaining filter taps */
295  tapCnt = numTaps % 0x4u;
296 
297  while(tapCnt > 0u)
298  {
299  /* Perform the multiply-accumulate */
300  *pb = *pb + (w * (*px++));
301  pb++;
302 
303  /* Decrement the loop counter */
304  tapCnt--;
305  }
306 
307  /* Advance state pointer by 1 for the next sample */
308  pState = pState + 1;
309 
310  /* Decrement the loop counter */
311  blkCnt--;
312  }
313 
314 
315  /* Processing is complete. Now copy the last numTaps - 1 samples to the
316  satrt of the state buffer. This prepares the state buffer for the
317  next function call. */
318 
319  /* Points to the start of the pState buffer */
320  pStateCurnt = S->pState;
321 
322  /* Loop unrolling for (numTaps - 1u) samples copy */
323  tapCnt = (numTaps - 1u) >> 2u;
324 
325  /* copy data */
326  while(tapCnt > 0u)
327  {
328  *pStateCurnt++ = *pState++;
329  *pStateCurnt++ = *pState++;
330  *pStateCurnt++ = *pState++;
331  *pStateCurnt++ = *pState++;
332 
333  /* Decrement the loop counter */
334  tapCnt--;
335  }
336 
337  /* Calculate remaining number of copies */
338  tapCnt = (numTaps - 1u) % 0x4u;
339 
340  /* Copy the remaining q31_t data */
341  while(tapCnt > 0u)
342  {
343  *pStateCurnt++ = *pState++;
344 
345  /* Decrement the loop counter */
346  tapCnt--;
347  }
348 
349 #else
350 
351  /* Run the below code for Cortex-M0 */
352 
353  while(blkCnt > 0u)
354  {
355  /* Copy the new input sample into the state buffer */
356  *pStateCurnt++ = *pSrc++;
357 
358  /* Initialize pState pointer */
359  px = pState;
360 
361  /* Initialize pCoeffs pointer */
362  pb = pCoeffs;
363 
364  /* Set the accumulator to zero */
365  sum = 0.0f;
366 
367  /* Loop over numTaps number of values */
368  tapCnt = numTaps;
369 
370  while(tapCnt > 0u)
371  {
372  /* Perform the multiply-accumulate */
373  sum += (*px++) * (*pb++);
374 
375  /* Decrement the loop counter */
376  tapCnt--;
377  }
378 
379  /* The result is stored in the destination buffer. */
380  *pOut++ = sum;
381 
382  /* Compute and store error */
383  d = (float32_t) (*pRef++);
384  e = d - sum;
385  *pErr++ = e;
386 
387  /* Weighting factor for the LMS version */
388  w = e * mu;
389 
390  /* Initialize pState pointer */
391  px = pState;
392 
393  /* Initialize pCoeffs pointer */
394  pb = pCoeffs;
395 
396  /* Loop over numTaps number of values */
397  tapCnt = numTaps;
398 
399  while(tapCnt > 0u)
400  {
401  /* Perform the multiply-accumulate */
402  *pb = *pb + (w * (*px++));
403  pb++;
404 
405  /* Decrement the loop counter */
406  tapCnt--;
407  }
408 
409  /* Advance state pointer by 1 for the next sample */
410  pState = pState + 1;
411 
412  /* Decrement the loop counter */
413  blkCnt--;
414  }
415 
416 
417  /* Processing is complete. Now copy the last numTaps - 1 samples to the
418  * start of the state buffer. This prepares the state buffer for the
419  * next function call. */
420 
421  /* Points to the start of the pState buffer */
422  pStateCurnt = S->pState;
423 
424  /* Copy (numTaps - 1u) samples */
425  tapCnt = (numTaps - 1u);
426 
427  /* Copy the data */
428  while(tapCnt > 0u)
429  {
430  *pStateCurnt++ = *pState++;
431 
432  /* Decrement the loop counter */
433  tapCnt--;
434  }
435 
436 #endif /* #ifndef ARM_MATH_CM0_FAMILY */
437 
438 }
439 
float float32_t
32-bit floating-point type definition.
Definition: arm_math.h:407
Instance structure for the floating-point LMS filter.
Definition: arm_math.h:3968
float32_t * pCoeffs
Definition: arm_math.h:3972
float32_t * pState
Definition: arm_math.h:3971
void arm_lms_f32(const arm_lms_instance_f32 *S, float32_t *pSrc, float32_t *pRef, float32_t *pOut, float32_t *pErr, uint32_t blockSize)
Processing function for floating-point LMS filter.
Definition: arm_lms_f32.c:181