BIQUADF32.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. #include "BIQUADF32.h"
  2. #include "Error.h"
  3. #define SNR_THRESHOLD 98
  4. /*
  5. Reference patterns are generated with
  6. a double precision computation.
  7. */
  8. #define REL_ERROR (1.2e-3)
  9. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  10. static __ALIGNED(8) float32_t coeffArray[32];
  11. #endif
  12. void BIQUADF32::test_biquad_cascade_df1_ref()
  13. {
  14. float32_t *statep = state.ptr();
  15. float32_t *debugstatep = debugstate.ptr();
  16. const float32_t *coefsp = coefs.ptr();
  17. const float32_t *inputp = inputs.ptr();
  18. float32_t *outp = output.ptr();
  19. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  20. arm_biquad_mod_coef_f32 *coefsmodp = (arm_biquad_mod_coef_f32*)vecCoefs.ptr();
  21. #endif
  22. int i,j;
  23. int blockSize;
  24. int numTaps;
  25. int nb=0;
  26. /*
  27. Python script is generating different tests with
  28. different blockSize and numTaps.
  29. We loop on those configs.
  30. */
  31. blockSize = inputs.nbSamples() >> 1;
  32. numTaps = coefs.nbSamples();
  33. /*
  34. The filter is initialized with the coefs, blockSize and numTaps.
  35. */
  36. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  37. arm_biquad_cascade_df1_mve_init_f32(&this->Sdf1,3,coefsp,coefsmodp,statep);
  38. #else
  39. arm_biquad_cascade_df1_init_f32(&this->Sdf1,3,coefsp,statep);
  40. #endif
  41. /*
  42. Python script is filtering a 2*blockSize number of samples.
  43. We do the same filtering in two pass to check (indirectly that
  44. the state management of the fir is working.)
  45. */
  46. arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
  47. memcpy(debugstatep,statep,3*4*sizeof(float32_t));
  48. debugstatep += 3*4;
  49. outp += blockSize;
  50. inputp += blockSize;
  51. arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
  52. outp += blockSize;
  53. memcpy(debugstatep,statep,3*4*sizeof(float32_t));
  54. debugstatep += 3*4;
  55. ASSERT_EMPTY_TAIL(output);
  56. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  57. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  58. }
  59. void BIQUADF32::test_biquad_cascade_df2T_ref()
  60. {
  61. float32_t *statep = state.ptr();
  62. #if !defined(ARM_MATH_NEON)
  63. const float32_t *coefsp = coefs.ptr();
  64. #else
  65. float32_t *coefsp = coefs.ptr();
  66. #endif
  67. const float32_t *inputp = inputs.ptr();
  68. float32_t *outp = output.ptr();
  69. int i,j;
  70. int blockSize;
  71. int numTaps;
  72. int nb=0;
  73. /*
  74. Python script is generating different tests with
  75. different blockSize and numTaps.
  76. We loop on those configs.
  77. */
  78. blockSize = inputs.nbSamples() >> 1;
  79. numTaps = coefs.nbSamples();
  80. /*
  81. The filter is initialized with the coefs, blockSize and numTaps.
  82. */
  83. #if !defined(ARM_MATH_NEON)
  84. arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,3,coefsp,statep);
  85. #else
  86. float32_t *vecCoefsPtr = vecCoefs.ptr();
  87. arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,
  88. 3,
  89. vecCoefsPtr,
  90. statep);
  91. // Those Neon coefs must be computed from original coefs
  92. arm_biquad_cascade_df2T_compute_coefs_f32(&this->Sdf2T,3,coefsp);
  93. #endif
  94. /*
  95. Python script is filtering a 2*blockSize number of samples.
  96. We do the same filtering in two pass to check (indirectly that
  97. the state management of the fir is working.)
  98. */
  99. arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
  100. outp += blockSize;
  101. inputp += blockSize;
  102. arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
  103. outp += blockSize;
  104. ASSERT_EMPTY_TAIL(output);
  105. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  106. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  107. }
  108. void BIQUADF32::test_biquad_cascade_df1_rand()
  109. {
  110. float32_t *statep = state.ptr();
  111. const float32_t *coefsp = coefs.ptr();
  112. const int16_t *configsp = configs.ptr();
  113. const float32_t *inputp = inputs.ptr();
  114. float32_t *outp = output.ptr();
  115. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  116. arm_biquad_mod_coef_f32 *coefsmodp = (arm_biquad_mod_coef_f32*)vecCoefs.ptr();
  117. #endif
  118. int blockSize;
  119. int numStages;
  120. int nb=0;
  121. int i;
  122. for(i=0;i < configs.nbSamples(); i+=2)
  123. {
  124. /*
  125. Python script is generating different tests with
  126. different blockSize and numTaps.
  127. We loop on those configs.
  128. */
  129. numStages = configsp[0];
  130. blockSize = configsp[1];
  131. configsp += 2;
  132. /*
  133. The filter is initialized with the coefs, blockSize and numTaps.
  134. */
  135. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  136. arm_biquad_cascade_df1_mve_init_f32(&this->Sdf1,numStages,coefsp,coefsmodp,statep);
  137. #else
  138. arm_biquad_cascade_df1_init_f32(&this->Sdf1,numStages,coefsp,statep);
  139. #endif
  140. /*
  141. Python script is filtering a 2*blockSize number of samples.
  142. We do the same filtering in two pass to check (indirectly that
  143. the state management of the fir is working.)
  144. */
  145. arm_biquad_cascade_df1_f32(&this->Sdf1,inputp,outp,blockSize);
  146. inputp += blockSize;
  147. outp += blockSize;
  148. coefsp += numStages * 5;
  149. }
  150. ASSERT_EMPTY_TAIL(output);
  151. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  152. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  153. }
  154. void BIQUADF32::test_biquad_cascade_df2T_rand()
  155. {
  156. float32_t *statep = state.ptr();
  157. const int16_t *configsp = configs.ptr();
  158. #if !defined(ARM_MATH_NEON)
  159. const float32_t *coefsp = coefs.ptr();
  160. #else
  161. float32_t *coefsp = coefs.ptr();
  162. #endif
  163. const float32_t *inputp = inputs.ptr();
  164. float32_t *outp = output.ptr();
  165. int blockSize;
  166. int numStages;
  167. int nb=0;
  168. int i;
  169. for(i=0;i < configs.nbSamples(); i+=2)
  170. {
  171. /*
  172. Python script is generating different tests with
  173. different blockSize and numTaps.
  174. We loop on those configs.
  175. */
  176. numStages = configsp[0];
  177. blockSize = configsp[1];
  178. configsp += 2;
  179. /*
  180. The filter is initialized with the coefs, blockSize and numTaps.
  181. */
  182. #if !defined(ARM_MATH_NEON)
  183. arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,numStages,coefsp,statep);
  184. #else
  185. float32_t *vecCoefsPtr = vecCoefs.ptr();
  186. arm_biquad_cascade_df2T_init_f32(&this->Sdf2T,
  187. numStages,
  188. vecCoefsPtr,
  189. statep);
  190. // Those Neon coefs must be computed from original coefs
  191. arm_biquad_cascade_df2T_compute_coefs_f32(&this->Sdf2T,numStages,coefsp);
  192. #endif
  193. coefsp += numStages * 5;
  194. /*
  195. Python script is filtering a 2*blockSize number of samples.
  196. We do the same filtering in two pass to check (indirectly that
  197. the state management of the fir is working.)
  198. */
  199. arm_biquad_cascade_df2T_f32(&this->Sdf2T,inputp,outp,blockSize);
  200. outp += blockSize;
  201. inputp += blockSize;
  202. }
  203. ASSERT_EMPTY_TAIL(output);
  204. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  205. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  206. }
  207. void BIQUADF32::test_biquad_cascade_stereo_df2T_rand()
  208. {
  209. float32_t *statep = state.ptr();
  210. const int16_t *configsp = configs.ptr();
  211. const float32_t *coefsp = coefs.ptr();
  212. const float32_t *inputp = inputs.ptr();
  213. float32_t *outp = output.ptr();
  214. int blockSize;
  215. int numStages;
  216. int nb=0;
  217. int i;
  218. for(i=0;i < configs.nbSamples(); i+=2)
  219. {
  220. /*
  221. Python script is generating different tests with
  222. different blockSize and numTaps.
  223. We loop on those configs.
  224. */
  225. numStages = configsp[0];
  226. blockSize = configsp[1];
  227. configsp += 2;
  228. /*
  229. The filter is initialized with the coefs, blockSize and numTaps.
  230. */
  231. arm_biquad_cascade_stereo_df2T_init_f32(&this->SStereodf2T,numStages,coefsp,statep);
  232. coefsp += numStages * 5;
  233. /*
  234. Python script is filtering a 2*blockSize number of samples.
  235. We do the same filtering in two pass to check (indirectly that
  236. the state management of the fir is working.)
  237. */
  238. arm_biquad_cascade_stereo_df2T_f32(&this->SStereodf2T,inputp,outp,blockSize);
  239. outp += 2*blockSize;
  240. inputp += 2*blockSize;
  241. }
  242. ASSERT_EMPTY_TAIL(output);
  243. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  244. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  245. }
  246. void BIQUADF32::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
  247. {
  248. Testing::nbSamples_t nb=MAX_NB_SAMPLES;
  249. switch(id)
  250. {
  251. case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_REF_1:
  252. debugstate.create(2*64,BIQUADF32::STATE_F32_ID,mgr);
  253. inputs.reload(BIQUADF32::BIQUADINPUTS_F32_ID,mgr);
  254. coefs.reload(BIQUADF32::BIQUADCOEFS_F32_ID,mgr);
  255. ref.reload(BIQUADF32::BIQUADREFS_F32_ID,mgr);
  256. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  257. /* Max num stages is 47 in Python script */
  258. vecCoefs.create(32*47,BIQUADF32::OUT_F32_ID,mgr);
  259. #endif
  260. break;
  261. case BIQUADF32::TEST_BIQUAD_CASCADE_DF2T_REF_2:
  262. vecCoefs.create(64,BIQUADF32::OUT_F32_ID,mgr);
  263. inputs.reload(BIQUADF32::BIQUADINPUTS_F32_ID,mgr);
  264. coefs.reload(BIQUADF32::BIQUADCOEFS_F32_ID,mgr);
  265. ref.reload(BIQUADF32::BIQUADREFS_F32_ID,mgr);
  266. break;
  267. case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_RAND_3:
  268. inputs.reload(BIQUADF32::ALLBIQUADINPUTS_F32_ID,mgr);
  269. coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
  270. ref.reload(BIQUADF32::ALLBIQUADREFS_F32_ID,mgr);
  271. configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
  272. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  273. /* Max num stages is 47 in Python script */
  274. vecCoefs.create(32*47,BIQUADF32::OUT_F32_ID,mgr);
  275. #endif
  276. break;
  277. case BIQUADF32::TEST_BIQUAD_CASCADE_DF2T_RAND_4:
  278. vecCoefs.create(512,BIQUADF32::OUT_F32_ID,mgr);
  279. inputs.reload(BIQUADF32::ALLBIQUADINPUTS_F32_ID,mgr);
  280. coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
  281. ref.reload(BIQUADF32::ALLBIQUADREFS_F32_ID,mgr);
  282. configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
  283. break;
  284. case BIQUADF32::TEST_BIQUAD_CASCADE_STEREO_DF2T_RAND_5:
  285. inputs.reload(BIQUADF32::ALLBIQUADSTEREOINPUTS_F32_ID,mgr);
  286. coefs.reload(BIQUADF32::ALLBIQUADCOEFS_F32_ID,mgr);
  287. ref.reload(BIQUADF32::ALLBIQUADSTEREOREFS_F32_ID,mgr);
  288. configs.reload(BIQUADF32::ALLBIQUADCONFIGS_S16_ID,mgr);
  289. break;
  290. }
  291. output.create(ref.nbSamples(),BIQUADF32::OUT_F32_ID,mgr);
  292. state.create(128,BIQUADF32::STATE_F32_ID,mgr);
  293. }
  294. void BIQUADF32::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
  295. {
  296. output.dump(mgr);
  297. switch(id)
  298. {
  299. case BIQUADF32::TEST_BIQUAD_CASCADE_DF1_REF_1:
  300. debugstate.dump(mgr);
  301. break;
  302. }
  303. }