]> git.gag.com Git - fw/stlink/blob - exampleF4/CMSIS/DSP_Lib/Examples/arm_signal_converge_example/arm_signal_converge_example_f32.c
Added all the F4 libraries to the project
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Examples / arm_signal_converge_example / arm_signal_converge_example_f32.c
1 /* ---------------------------------------------------------------------- 
2 * Copyright (C) 2010 ARM Limited. All rights reserved.   
3 *  
4 * $Date:        29. November 2010  
5 * $Revision:    V1.0.3
6 *  
7 * Project:          CMSIS DSP Library  
8 * Title:            arm_signal_converge_example_f32.c             
9 *  
10 * Description:  Example code demonstrating convergence of an adaptive 
11 *               filter. 
12
13 * Target Processor: Cortex-M4/Cortex-M3  
14 *
15 *
16 * Version 1.0.3 2010/11/29 
17 *    Re-organized the CMSIS folders and updated documentation. 
18
19 * Version 1.0.1 2010/10/05 KK 
20 *    Production release and review comments incorporated.  
21 *
22 * Version 1.0.0 2010/09/20 KK
23 *    Production release and review comments incorporated.
24 * ------------------------------------------------------------------- */ 
25  
26 /** 
27  * @ingroup groupExamples 
28  */ 
29  
30 /**    
31  * @defgroup SignalConvergence Signal Convergence Example    
32  * 
33  * \par Description: 
34  * \par
35  * Demonstrates the ability of an adaptive filter to "learn" the transfer function of 
36  * a FIR lowpass filter using the Normalized LMS Filter, Finite Impulse 
37  * Response (FIR) Filter, and Basic Math Functions.
38  * 
39  * \par Algorithm:
40  * \par
41  * The figure below illustrates the signal flow in this example. Uniformly distributed white 
42  * noise is passed through an FIR lowpass filter. The output of the FIR filter serves as the 
43  * reference input of the adaptive filter (normalized LMS filter). The white noise is input 
44  * to the adaptive filter. The adaptive filter learns the transfer function of the FIR filter.
45  * The filter outputs two signals: (1) the output of the internal adaptive FIR filter, and 
46  * (2) the error signal which is the difference between the adaptive filter and the reference 
47  * output of the FIR filter. Over time as the adaptive filter learns the transfer function 
48  * of the FIR filter, the first output approaches the reference output of the FIR filter,
49  * and the error signal approaches zero. 
50  * \par
51  * The adaptive filter converges properly even if the input signal has a large dynamic 
52  * range (i.e., varies from small to large values). The coefficients of the adaptive filter 
53  * are initially zero, and then converge over 1536 samples. The internal function test_signal_converge() 
54  * implements the stopping condition. The function checks if all of the values of the error signal have a 
55  * magnitude below a threshold DELTA. 
56  * 
57  * \par Block Diagram:
58  * \par
59  * \image html SignalFlow.gif 
60  *
61  *
62  * \par Variables Description:
63  * \par
64  * \li \c testInput_f32 points to the input data
65  * \li \c firStateF32 points to FIR state buffer
66  * \li \c lmsStateF32 points to Normalised Least mean square FIR filter state buffer
67  * \li \c FIRCoeff_f32 points to coefficient buffer
68  * \li \c lmsNormCoeff_f32 points to Normalised Least mean square FIR filter coefficient buffer
69  * \li \c wire1, wir2, wire3 temporary buffers
70  * \li \c errOutput, err_signal temporary error buffers 
71  *
72  * \par CMSIS DSP Software Library Functions Used:
73  * \par
74  * - arm_lms_norm_init_f32()
75  * - arm_fir_init_f32()
76  * - arm_fir_f32()
77  * - arm_lms_norm_f32()
78  * - arm_scale_f32()
79  * - arm_abs_f32()
80  * - arm_sub_f32()
81  * - arm_min_f32()
82  * - arm_copy_f32()
83  *
84  * <b> Refer  </b> 
85  * \link arm_signal_converge_example_f32.c \endlink
86  * 
87  */  
88  
89  
90 /** \example arm_signal_converge_example_f32.c 
91   */  
92      
93 #include "arm_math.h" 
94 #include "math_helper.h" 
95  
96 /* ---------------------------------------------------------------------- 
97 ** Global defines for the simulation 
98 * ------------------------------------------------------------------- */ 
99  
100 #define TEST_LENGTH_SAMPLES 1536 
101 #define NUMTAPS                         32 
102 #define BLOCKSIZE                       32 
103 #define DELTA_ERROR         0.000001f 
104 #define DELTA_COEFF         0.0001f 
105 #define MU                                      0.5f 
106  
107 #define NUMFRAMES (TEST_LENGTH_SAMPLES / BLOCKSIZE) 
108  
109 /* ---------------------------------------------------------------------- 
110 * Declare FIR state buffers and structure  
111 * ------------------------------------------------------------------- */ 
112   
113 float32_t firStateF32[NUMTAPS + BLOCKSIZE];  
114 arm_fir_instance_f32 LPF_instance; 
115  
116 /* ---------------------------------------------------------------------- 
117 * Declare LMSNorm state buffers and structure  
118 * ------------------------------------------------------------------- */ 
119   
120 float32_t lmsStateF32[NUMTAPS + BLOCKSIZE];  
121 float32_t errOutput[TEST_LENGTH_SAMPLES]; 
122 arm_lms_norm_instance_f32 lmsNorm_instance; 
123  
124  
125 /* ---------------------------------------------------------------------- 
126 * Function Declarations for Signal Convergence Example  
127 * ------------------------------------------------------------------- */ 
128  
129 arm_status test_signal_converge_example( void ); 
130  
131  
132 /* ---------------------------------------------------------------------- 
133 * Internal functions 
134 * ------------------------------------------------------------------- */ 
135 arm_status test_signal_converge(float32_t* err_signal, 
136                                                      uint32_t blockSize); 
137  
138 void getinput(float32_t* input, 
139                  uint32_t fr_cnt,  
140              uint32_t blockSize);  
141  
142 /* ---------------------------------------------------------------------- 
143 * External Declarations for FIR F32 module Test 
144 * ------------------------------------------------------------------- */ 
145 extern float32_t testInput_f32[TEST_LENGTH_SAMPLES]; 
146 extern float32_t lmsNormCoeff_f32[32]; 
147 extern const float32_t FIRCoeff_f32[32]; 
148 extern arm_lms_norm_instance_f32 lmsNorm_instance; 
149  
150 /* ---------------------------------------------------------------------- 
151 * Declare I/O buffers  
152 * ------------------------------------------------------------------- */ 
153  
154 float32_t wire1[BLOCKSIZE]; 
155 float32_t wire2[BLOCKSIZE]; 
156 float32_t wire3[BLOCKSIZE]; 
157 float32_t err_signal[BLOCKSIZE]; 
158  
159 /* ---------------------------------------------------------------------- 
160 * Signal converge test 
161 * ------------------------------------------------------------------- */ 
162  
163 int32_t main(void) 
164
165   uint32_t i; 
166   arm_status status; 
167   uint32_t index; 
168   float32_t minValue; 
169  
170   /* Initialize the LMSNorm data structure */ 
171   arm_lms_norm_init_f32(&lmsNorm_instance, NUMTAPS, lmsNormCoeff_f32, lmsStateF32, MU, BLOCKSIZE); 
172  
173   /* Initialize the FIR data structure */ 
174   arm_fir_init_f32(&LPF_instance, NUMTAPS, (float32_t *)FIRCoeff_f32, firStateF32, BLOCKSIZE); 
175  
176   /* ---------------------------------------------------------------------- 
177   * Loop over the frames of data and execute each of the processing 
178   * functions in the system. 
179   * ------------------------------------------------------------------- */ 
180  
181   for(i=0; i < NUMFRAMES; i++)  
182     { 
183       /* Read the input data - uniformly distributed random noise - into wire1 */  
184       arm_copy_f32(testInput_f32 + (i * BLOCKSIZE), wire1, BLOCKSIZE); 
185  
186       /* Execute the FIR processing function.  Input wire1 and output wire2 */  
187       arm_fir_f32(&LPF_instance, wire1, wire2, BLOCKSIZE); 
188        
189       /* Execute the LMS Norm processing function*/  
190  
191       arm_lms_norm_f32(&lmsNorm_instance, /* LMSNorm instance */ 
192                        wire1,                     /* Input signal */  
193                        wire2,                             /* Reference Signal */ 
194                        wire3,                             /* Converged Signal */ 
195                        err_signal,                        /* Error Signal, this will become small as the signal converges */ 
196                        BLOCKSIZE);                        /* BlockSize */ 
197  
198       /* apply overall gain */  
199       arm_scale_f32(wire3, 5, wire3, BLOCKSIZE);         /* in-place buffer */  
200     } 
201  
202   status = ARM_MATH_SUCCESS; 
203  
204   /* ------------------------------------------------------------------------------- 
205   * Test whether the error signal has reached towards 0. 
206   * ----------------------------------------------------------------------------- */ 
207  
208   arm_abs_f32(err_signal, err_signal, BLOCKSIZE); 
209   arm_min_f32(err_signal, BLOCKSIZE, &minValue, &index); 
210  
211   if (minValue > DELTA_ERROR) 
212   { 
213       status = ARM_MATH_TEST_FAILURE; 
214   } 
215  
216   /* ---------------------------------------------------------------------- 
217   * Test whether the filter coefficients have converged. 
218   * ------------------------------------------------------------------- */ 
219  
220   arm_sub_f32((float32_t *)FIRCoeff_f32, lmsNormCoeff_f32, lmsNormCoeff_f32, NUMTAPS); 
221  
222   arm_abs_f32(lmsNormCoeff_f32, lmsNormCoeff_f32, NUMTAPS); 
223   arm_min_f32(lmsNormCoeff_f32, NUMTAPS, &minValue, &index); 
224  
225   if (minValue > DELTA_COEFF) 
226   { 
227       status = ARM_MATH_TEST_FAILURE; 
228   } 
229  
230   /* ---------------------------------------------------------------------- 
231   * Loop here if the signals did not pass the convergence check. 
232   * This denotes a test failure 
233   * ------------------------------------------------------------------- */ 
234  
235   if( status != ARM_MATH_SUCCESS) 
236   { 
237       while(1); 
238   } 
239
240     while(1);                             /* main function does not return */
241
242  
243  /** \endlink */ 
244                  
245  
246