BIQUADF32.cpp 12 KB

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