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