BIQUADF32.cpp 12 KB

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