1 #include "BIQUADF32.h"
2 #include <stdio.h>
3 #include "Error.h"
4 
5 #define SNR_THRESHOLD 98
6 
7 /*
8 
9 Reference patterns are generated with
10 a double precision computation.
11 
12 */
13 #define REL_ERROR (1.2e-3)
14 
15 
test_biquad_cascade_df1_ref()16     void BIQUADF32::test_biquad_cascade_df1_ref()
17     {
18 
19 
20         float32_t *statep = state.ptr();
21         float32_t *debugstatep = debugstate.ptr();
22 
23         const float32_t *coefsp = coefs.ptr();
24 
25         const float32_t *inputp = inputs.ptr();
26         float32_t *outp = output.ptr();
27 
28         #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
29         arm_biquad_mod_coef_f32 *coefsmodp = (arm_biquad_mod_coef_f32*)vecCoefs.ptr();
30         #endif
31 
32         int blockSize;
33 
34 
35 
36         /*
37 
38         Python script is generating different tests with
39         different blockSize and numTaps.
40 
41         We loop on those configs.
42 
43         */
44 
45            blockSize = inputs.nbSamples() >> 1;
46 
47            /*
48 
49            The filter is initialized with the coefs, blockSize and numTaps.
50 
51            */
52 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
53            arm_biquad_cascade_df1_mve_init_f32(&this->Sdf1,3,coefsp,coefsmodp,statep);
54 #else
55            arm_biquad_cascade_df1_init_f32(&this->Sdf1,3,coefsp,statep);
56 #endif
57 
58            /*
59 
60            Python script is filtering a 2*blockSize number of samples.
61            We do the same filtering in two pass to check (indirectly that
62            the state management of the fir is working.)
63 
64            */
65 
66            arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
67 
68            memcpy(debugstatep,statep,3*4*sizeof(float32_t));
69            debugstatep += 3*4;
70 
71            outp += blockSize;
72 
73            inputp += blockSize;
74            arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
75            outp += blockSize;
76 
77            memcpy(debugstatep,statep,3*4*sizeof(float32_t));
78            debugstatep += 3*4;
79 
80            ASSERT_EMPTY_TAIL(output);
81 
82            ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
83 
84            ASSERT_REL_ERROR(output,ref,REL_ERROR);
85 
86 
87     }
88 
test_biquad_cascade_df2T_ref()89     void BIQUADF32::test_biquad_cascade_df2T_ref()
90     {
91 
92 
93         float32_t *statep = state.ptr();
94 
95         const float32_t *coefsp = coefs.ptr();
96 
97 
98         const float32_t *inputp = inputs.ptr();
99         float32_t *outp = output.ptr();
100 
101         int blockSize;
102 
103 
104 
105         /*
106 
107         Python script is generating different tests with
108         different blockSize and numTaps.
109 
110         We loop on those configs.
111 
112         */
113 
114            blockSize = inputs.nbSamples() >> 1;
115 
116            /*
117 
118            The filter is initialized with the coefs, blockSize and numTaps.
119 
120            */
121 #if !defined(ARM_MATH_NEON)
122            arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,3,coefsp,statep);
123 #else
124            float32_t *vecCoefsPtr = vecCoefs.ptr();
125 
126            // Those Neon coefs must be computed from original coefs
127            arm_biquad_cascade_df2T_compute_coefs_f32(3,coefsp,vecCoefsPtr);
128 
129            arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,
130                     3,
131                     vecCoefsPtr,
132                     statep);
133 
134 
135 #endif
136 
137            /*
138 
139            Python script is filtering a 2*blockSize number of samples.
140            We do the same filtering in two pass to check (indirectly that
141            the state management of the fir is working.)
142 
143            */
144 
145            arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
146            outp += blockSize;
147 
148 
149            inputp += blockSize;
150            arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
151            outp += blockSize;
152 
153 
154            ASSERT_EMPTY_TAIL(output);
155 
156            ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
157 
158            ASSERT_REL_ERROR(output,ref,REL_ERROR);
159 
160 
161     }
162 
test_biquad_cascade_df1_rand()163     void BIQUADF32::test_biquad_cascade_df1_rand()
164     {
165 
166 
167         float32_t *statep = state.ptr();
168 
169         const float32_t *coefsp = coefs.ptr();
170         const int16_t *configsp = configs.ptr();
171 
172         const float32_t *inputp = inputs.ptr();
173         float32_t *outp = output.ptr();
174 
175         #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
176         arm_biquad_mod_coef_f32 *coefsmodp = (arm_biquad_mod_coef_f32*)vecCoefs.ptr();
177         #endif
178 
179         int blockSize;
180         int numStages;
181         unsigned long i;
182 
183 
184 
185         for(i=0;i < configs.nbSamples(); i+=2)
186         {
187         /*
188 
189         Python script is generating different tests with
190         different blockSize and numTaps.
191 
192         We loop on those configs.
193 
194         */
195 
196 
197            numStages = configsp[0];
198            blockSize = configsp[1];
199 
200            configsp += 2;
201 
202            /*
203 
204            The filter is initialized with the coefs, blockSize and numTaps.
205 
206            */
207 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
208            arm_biquad_cascade_df1_mve_init_f32(&this->Sdf1,numStages,coefsp,coefsmodp,statep);
209 #else
210            arm_biquad_cascade_df1_init_f32(&this->Sdf1,numStages,coefsp,statep);
211 #endif
212 
213 
214            /*
215 
216            Python script is filtering a 2*blockSize number of samples.
217            We do the same filtering in two pass to check (indirectly that
218            the state management of the fir is working.)
219 
220            */
221 
222            arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
223 
224            inputp += blockSize;
225            outp += blockSize;
226            coefsp += numStages * 5;
227 
228 
229 
230         }
231            ASSERT_EMPTY_TAIL(output);
232 
233            ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
234 
235            ASSERT_REL_ERROR(output,ref,REL_ERROR);
236 
237 
238     }
239 
test_biquad_cascade_df2T_rand()240     void BIQUADF32::test_biquad_cascade_df2T_rand()
241     {
242 
243 
244         float32_t *statep = state.ptr();
245         const int16_t *configsp = configs.ptr();
246 
247 #if !defined(ARM_MATH_NEON)
248         const float32_t *coefsp = coefs.ptr();
249 #else
250         float32_t *coefsp = coefs.ptr();
251 #endif
252 
253         const float32_t *inputp = inputs.ptr();
254         float32_t *outp = output.ptr();
255 
256         int blockSize;
257         int numStages;
258 
259         unsigned long i;
260 
261 
262 
263         for(i=0;i < configs.nbSamples(); i+=2)
264         {
265 
266         /*
267 
268         Python script is generating different tests with
269         different blockSize and numTaps.
270 
271         We loop on those configs.
272 
273         */
274 
275            numStages = configsp[0];
276            blockSize = configsp[1];
277 
278            configsp += 2;
279 
280 
281 
282            /*
283 
284            The filter is initialized with the coefs, blockSize and numTaps.
285 
286            */
287 #if !defined(ARM_MATH_NEON)
288            arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,numStages,coefsp,statep);
289 #else
290            float32_t *vecCoefsPtr = vecCoefs.ptr();
291 
292            // Those Neon coefs must be computed from original coefs
293            arm_biquad_cascade_df2T_compute_coefs_f32(numStages,coefsp,vecCoefsPtr);
294 
295            arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,
296                     numStages,
297                     vecCoefsPtr,
298                     statep);
299 
300 
301 #endif
302            coefsp += numStages * 5;
303 
304            /*
305 
306            Python script is filtering a 2*blockSize number of samples.
307            We do the same filtering in two pass to check (indirectly that
308            the state management of the fir is working.)
309 
310            */
311 
312            arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
313            outp += blockSize;
314            inputp += blockSize;
315 
316         }
317 
318            ASSERT_EMPTY_TAIL(output);
319 
320            ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
321 
322            ASSERT_REL_ERROR(output,ref,REL_ERROR);
323 
324 
325     }
326 
test_biquad_cascade_stereo_df2T_rand()327     void BIQUADF32::test_biquad_cascade_stereo_df2T_rand()
328     {
329 
330 
331         float32_t *statep = state.ptr();
332         const int16_t *configsp = configs.ptr();
333 
334         const float32_t *coefsp = coefs.ptr();
335 
336 
337         const float32_t *inputp = inputs.ptr();
338         float32_t *outp = output.ptr();
339 
340         int blockSize;
341         int numStages;
342 
343         unsigned long i;
344 
345 
346 
347         for(i=0;i < configs.nbSamples(); i+=2)
348         {
349 
350         /*
351 
352         Python script is generating different tests with
353         different blockSize and numTaps.
354 
355         We loop on those configs.
356 
357         */
358 
359            numStages = configsp[0];
360            blockSize = configsp[1];
361 
362            configsp += 2;
363 
364 
365 
366            /*
367 
368            The filter is initialized with the coefs, blockSize and numTaps.
369 
370            */
371            arm_biquad_cascade_stereo_df2T_init_f32(&this->SStereodf2T,numStages,coefsp,statep);
372 
373            coefsp += numStages * 5;
374 
375            /*
376 
377            Python script is filtering a 2*blockSize number of samples.
378            We do the same filtering in two pass to check (indirectly that
379            the state management of the fir is working.)
380 
381            */
382 
383            arm_biquad_cascade_stereo_df2T_f32(&this->SStereodf2T,inputp,outp,blockSize);
384            outp += 2*blockSize;
385            inputp += 2*blockSize;
386 
387         }
388 
389            ASSERT_EMPTY_TAIL(output);
390 
391            ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
392 
393            ASSERT_REL_ERROR(output,ref,REL_ERROR);
394 
395 
396     }
397 
setUp(Testing::testID_t id,std::vector<Testing::param_t> & params,Client::PatternMgr * mgr)398     void BIQUADF32::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
399     {
400 
401        (void)params;
402        switch(id)
403        {
404         case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_REF_1:
405             debugstate.create(2*64,BIQUADF32::STATE_F32_ID,mgr);
406 
407             inputs.reload(BIQUADF32::BIQUADINPUTS_F32_ID,mgr);
408             coefs.reload(BIQUADF32::BIQUADCOEFS_F32_ID,mgr);
409             ref.reload(BIQUADF32::BIQUADREFS_F32_ID,mgr);
410             #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
411             /* Max num stages is 47 in Python script */
412             vecCoefs.create(32*47,BIQUADF32::OUT_F32_ID,mgr);
413             #endif
414         break;
415 
416         case BIQUADF32::TEST_BIQUAD_CASCADE_DF2T_REF_2:
417            vecCoefs.create(64,BIQUADF32::OUT_F32_ID,mgr);
418 
419            inputs.reload(BIQUADF32::BIQUADINPUTS_F32_ID,mgr);
420            coefs.reload(BIQUADF32::BIQUADCOEFS_F32_ID,mgr);
421            ref.reload(BIQUADF32::BIQUADREFS_F32_ID,mgr);
422         break;
423 
424         case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_RAND_3:
425 
426             inputs.reload(BIQUADF32::ALLBIQUADINPUTS_F32_ID,mgr);
427             coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
428             ref.reload(BIQUADF32::ALLBIQUADREFS_F32_ID,mgr);
429             configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
430             #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
431             /* Max num stages is 47 in Python script */
432             vecCoefs.create(32*47,BIQUADF32::OUT_F32_ID,mgr);
433             #endif
434         break;
435 
436         case BIQUADF32::TEST_BIQUAD_CASCADE_DF2T_RAND_4:
437            vecCoefs.create(512,BIQUADF32::OUT_F32_ID,mgr);
438 
439            inputs.reload(BIQUADF32::ALLBIQUADINPUTS_F32_ID,mgr);
440            coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
441            ref.reload(BIQUADF32::ALLBIQUADREFS_F32_ID,mgr);
442            configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
443         break;
444 
445         case BIQUADF32::TEST_BIQUAD_CASCADE_STEREO_DF2T_RAND_5:
446 
447            inputs.reload(BIQUADF32::ALLBIQUADSTEREOINPUTS_F32_ID,mgr);
448            coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
449            ref.reload(BIQUADF32::ALLBIQUADSTEREOREFS_F32_ID,mgr);
450            configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
451         break;
452 
453        }
454 
455 
456 
457 
458        output.create(ref.nbSamples(),BIQUADF32::OUT_F32_ID,mgr);
459 
460        state.create(128,BIQUADF32::STATE_F32_ID,mgr);
461 
462 
463     }
464 
tearDown(Testing::testID_t id,Client::PatternMgr * mgr)465     void BIQUADF32::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
466     {
467         (void)id;
468         output.dump(mgr);
469         switch(id)
470         {
471             case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_REF_1:
472                debugstate.dump(mgr);
473             break;
474         }
475     }
476