1 #include "FIRQ31.h"
2 #include <stdio.h>
3 #include "Error.h"
4 
5 #define SNR_THRESHOLD 100
6 
7 #define ABS_ERROR_Q31 ((q31_t)2)
8 
9 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
10 static __ALIGNED(8) q31_t coeffArray[32];
11 #endif
12 
checkInnerTail(q31_t * b)13 static void checkInnerTail(q31_t *b)
14 {
15     ASSERT_TRUE(b[0] == 0);
16     ASSERT_TRUE(b[1] == 0);
17     ASSERT_TRUE(b[2] == 0);
18     ASSERT_TRUE(b[3] == 0);
19 }
20 
21 // Coef must be padded to a multiple of 4
22 #define FIRCOEFPADDING 2
23 
test_fir_q31()24     void FIRQ31::test_fir_q31()
25     {
26 
27 
28         const int16_t *configp = configs.ptr();
29         q31_t *statep = state.ptr();
30         const q31_t *orgcoefsp = coefs.ptr();
31 
32         const q31_t *coefsp;
33         const q31_t *inputp = inputs.ptr();
34         q31_t *outp = output.ptr();
35 
36         unsigned long i;
37 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
38         int j;
39         int round;
40 #endif
41         int blockSize;
42         int numTaps;
43 
44         /*
45 
46         Python script is generating different tests with
47         different blockSize and numTaps.
48 
49         We loop on those configs.
50 
51         */
52         for(i=0; i < configs.nbSamples() ; i += 2)
53         {
54            blockSize = configp[0];
55            numTaps = configp[1];
56 
57 #if defined(ARM_MATH_MVEI) && !defined(ARM_MATH_AUTOVECTORIZE)
58            /* Copy coefficients and pad to zero
59            */
60            memset(coeffArray,127,32*sizeof(q31_t));
61            round = numTaps >> FIRCOEFPADDING;
62            if ((round << FIRCOEFPADDING) < numTaps)
63            {
64              round ++;
65            }
66            round = round<<FIRCOEFPADDING;
67            memset(coeffArray,0,round*sizeof(q31_t));
68 
69            //printf("blockSize=%d, numTaps=%d, round=%d (%d)\n",blockSize,numTaps,round,round - numTaps);
70 
71 
72            for(j=0;j < numTaps; j++)
73            {
74               coeffArray[j] = orgcoefsp[j];
75            }
76 
77            coefsp = coeffArray;
78 #else
79            coefsp = orgcoefsp;
80 #endif
81 
82            /*
83 
84            The filter is initialized with the coefs, blockSize and numTaps.
85 
86            */
87            arm_fir_init_q31(&this->S,numTaps,coefsp,statep,blockSize);
88 
89            /*
90 
91            Input pointer is reset since the same input pattern is used
92 
93            */
94            inputp = inputs.ptr();
95 
96            /*
97 
98            Python script is filtering a 2*blockSize number of samples.
99            We do the same filtering in two pass to check (indirectly that
100            the state management of the fir is working.)
101 
102            */
103            arm_fir_q31(&this->S,inputp,outp,blockSize);
104            outp += blockSize;
105            checkInnerTail(outp);
106 
107            inputp += blockSize;
108            arm_fir_q31(&this->S,inputp,outp,blockSize);
109            outp += blockSize;
110            checkInnerTail(outp);
111 
112            configp += 2;
113            orgcoefsp += numTaps;
114 
115 
116 
117         }
118 
119         ASSERT_EMPTY_TAIL(output);
120 
121         ASSERT_SNR(output,ref,(q31_t)SNR_THRESHOLD);
122 
123         ASSERT_NEAR_EQ(output,ref,ABS_ERROR_Q31);
124 
125     }
126 
127 
setUp(Testing::testID_t id,std::vector<Testing::param_t> & params,Client::PatternMgr * mgr)128     void FIRQ31::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
129     {
130 
131        (void)params;
132        switch(id)
133        {
134         case FIRQ31::TEST_FIR_Q31_1:
135 
136         break;
137 
138        }
139 
140 
141        inputs.reload(FIRQ31::FIRINPUTS_Q31_ID,mgr);
142        coefs.reload(FIRQ31::FIRCOEFS_Q31_ID,mgr);
143        configs.reload(FIRQ31::FIRCONFIGS_S16_ID,mgr);
144        ref.reload(FIRQ31::FIRREFS_Q31_ID,mgr);
145 
146        output.create(ref.nbSamples(),FIRQ31::OUT_Q31_ID,mgr);
147        /* > Max blockSize + numTaps - 1 as generated by Python script */
148        state.create(47 + 47+47,FIRQ31::OUT_Q31_ID,mgr);
149     }
150 
tearDown(Testing::testID_t id,Client::PatternMgr * mgr)151     void FIRQ31::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
152     {
153         (void)id;
154         output.dump(mgr);
155     }
156