BIQUADF32.cpp 12 KB

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