FIRF32.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include "FIRF32.h"
  2. #include <stdio.h>
  3. #include "Error.h"
  4. #define SNR_THRESHOLD 120
  5. /*
  6. Reference patterns are generated with
  7. a double precision computation.
  8. */
  9. #define REL_ERROR (3.0e-5)
  10. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  11. static __ALIGNED(8) float32_t coeffArray[32];
  12. #endif
  13. static void checkInnerTail(float32_t *b)
  14. {
  15. ASSERT_TRUE(b[0] == 0.0f);
  16. ASSERT_TRUE(b[1] == 0.0f);
  17. ASSERT_TRUE(b[2] == 0.0f);
  18. ASSERT_TRUE(b[3] == 0.0f);
  19. }
  20. // Coef must be padded to a multiple of 4
  21. #define FIRCOEFPADDING 2
  22. void FIRF32::test_fir_f32()
  23. {
  24. const int16_t *configp = configs.ptr();
  25. float32_t *statep = state.ptr();
  26. const float32_t *orgcoefsp = coefs.ptr();
  27. const float32_t *coefsp;
  28. const float32_t *inputp = inputs.ptr();
  29. float32_t *outp = output.ptr();
  30. unsigned long i;
  31. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  32. int j;
  33. #endif
  34. int blockSize;
  35. int numTaps;
  36. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  37. int round;
  38. #endif
  39. int nb=0;
  40. /*
  41. Python script is generating different tests with
  42. different blockSize and numTaps.
  43. We loop on those configs.
  44. */
  45. for(i=0; i < configs.nbSamples() ; i += 2)
  46. {
  47. blockSize = configp[0];
  48. numTaps = configp[1];
  49. nb += 2*blockSize;
  50. #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
  51. /* Copy coefficients and pad to zero
  52. */
  53. memset(coeffArray,127,32*sizeof(float32_t));
  54. round = numTaps >> FIRCOEFPADDING;
  55. if ((round << FIRCOEFPADDING) < numTaps)
  56. {
  57. round ++;
  58. }
  59. round = round<<FIRCOEFPADDING;
  60. memset(coeffArray,0,round*sizeof(float32_t));
  61. //printf("blockSize=%d, numTaps=%d, round=%d (%d)\n",blockSize,numTaps,round,round - numTaps);
  62. for(j=0;j < numTaps; j++)
  63. {
  64. coeffArray[j] = orgcoefsp[j];
  65. }
  66. coefsp = coeffArray;
  67. #else
  68. coefsp = orgcoefsp;
  69. #endif
  70. /*
  71. The filter is initialized with the coefs, blockSize and numTaps.
  72. */
  73. arm_fir_init_f32(&this->S,numTaps,coefsp,statep,blockSize);
  74. /*
  75. Input pointer is reset since the same input pattern is used
  76. */
  77. inputp = inputs.ptr();
  78. /*
  79. Python script is filtering a 2*blockSize number of samples.
  80. We do the same filtering in two pass to check (indirectly that
  81. the state management of the fir is working.)
  82. */
  83. arm_fir_f32(&this->S,inputp,outp,blockSize);
  84. outp += blockSize;
  85. checkInnerTail(outp);
  86. inputp += blockSize;
  87. arm_fir_f32(&this->S,inputp,outp,blockSize);
  88. outp += blockSize;
  89. checkInnerTail(outp);
  90. configp += 2;
  91. orgcoefsp += numTaps;
  92. }
  93. ASSERT_EMPTY_TAIL(output);
  94. ASSERT_SNR(output,ref,(float32_t)SNR_THRESHOLD);
  95. ASSERT_REL_ERROR(output,ref,REL_ERROR);
  96. }
  97. void FIRF32::setUp(Testing::testID_t id,std::vector<Testing::param_t>& params,Client::PatternMgr *mgr)
  98. {
  99. (void)params;
  100. switch(id)
  101. {
  102. case FIRF32::TEST_FIR_F32_1:
  103. break;
  104. }
  105. inputs.reload(FIRF32::FIRINPUTS_F32_ID,mgr);
  106. coefs.reload(FIRF32::FIRCOEFS_F32_ID,mgr);
  107. configs.reload(FIRF32::FIRCONFIGS_S16_ID,mgr);
  108. ref.reload(FIRF32::FIRREFS_F32_ID,mgr);
  109. output.create(ref.nbSamples(),FIRF32::OUT_F32_ID,mgr);
  110. /* Max 2*blockSize + numTaps - 1 as generated by Python script
  111. A temp buffer blockSize is used by Helium implementation.
  112. It is at beginning of state buffer and is NOT the state
  113. of the FIR which is in the following part.
  114. */
  115. state.create(47+47,FIRF32::OUT_F32_ID,mgr);
  116. }
  117. void FIRF32::tearDown(Testing::testID_t id,Client::PatternMgr *mgr)
  118. {
  119. (void)id;
  120. output.dump(mgr);
  121. }