ains4.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "include.h"
  2. #include "api_ains4.h"
  3. #if (AINS4_EN)
  4. #define PART_LEN (AINS4_PART_LEN << 1)
  5. #define PART_LEN2 (PART_LEN << 1)
  6. #define PART_HALF_LEN (PART_LEN / 2)
  7. #define HANN_SHIFT (16)
  8. typedef struct {
  9. u8 sysclk;
  10. bool init;
  11. } ains4_cb_t;
  12. static ains4_cb_t ains4_cb;
  13. typedef struct {
  14. // s16 input[PART_LEN];
  15. // s16 fft_output[PART_LEN];
  16. // s16 output[PART_LEN];
  17. s16 input[128];
  18. s16 fft_output[128];
  19. s16 output[128];
  20. u8 iptr;
  21. u8 optr;
  22. } ains4_rdft_t;
  23. static ains4_rdft_t ains4_rdft AT(.ains4_buf.rdft);
  24. static struct nr_buf_t {
  25. // int fft[PART_LEN2];
  26. // s16 xbuf[PART_LEN2];
  27. // int outBuf[PART_LEN];
  28. int fft[256];
  29. s16 xbuf[256];
  30. int outBuf[128];
  31. } nr_buf AT(.fft_buf.buf);
  32. #if (PART_LEN == 120)
  33. //120
  34. AT(.fft_rodata)
  35. static const unsigned short sqrt_Hanning[121] = {
  36. 854, 1708, 2562, 3416, 4268, 5121, 5972, 6822, 7671, 8519, 9365, 10210, 11053, 11894, 12733,
  37. 13570, 14405, 15237, 16066, 16893, 17717, 18538, 19356, 20170, 20982, 21789, 22593, 23393,
  38. 24189, 24981, 25769, 26552, 27331, 28105, 28874, 29638, 30398, 31152, 31901, 32645, 33383,
  39. 34115, 34841, 35562, 36277, 36985, 37687, 38383, 39072, 39754, 40430, 41099, 41761, 42416,
  40. 43064, 43704, 44337, 44962, 45580, 46190, 46792, 47386, 47972, 48550, 49120, 49681, 50234,
  41. 50778, 51314, 51841, 52359, 52869, 53369, 53860, 54342, 54815, 55279, 55733, 56178, 56613,
  42. 57038, 57454, 57860, 58257, 58643, 59019, 59386, 59742, 60088, 60424, 60750, 61065, 61370,
  43. 61664, 61948, 62222, 62485, 62737, 62979, 63210, 63430, 63639, 63838, 64026, 64203, 64369,
  44. 64524, 64668, 64801, 64923, 65034, 65134, 65223, 65301, 65368, 65423, 65468, 65501, 65523,
  45. 65535, 65535,
  46. };
  47. #else
  48. //128
  49. AT(.fft_rodata)
  50. static const unsigned short sqrt_Hanning[129] = {
  51. 0x0000,0x0321,0x0642,0x0963,0x0C83,0x0FA3,0x12C2,0x15E1,
  52. 0x18FF,0x1C1C,0x1F37,0x2252,0x256B,0x2883,0x2B99,0x2EAE,
  53. 0x31C0,0x34D1,0x37E0,0x3AED,0x3DF7,0x40FF,0x4405,0x4708,
  54. 0x4A08,0x4D06,0x5000,0x52F8,0x55EC,0x58DD,0x5BCA,0x5EB5,
  55. 0x619B,0x647E,0x675D,0x6A38,0x6D0E,0x6FE1,0x72AF,0x7579,
  56. 0x783F,0x7B00,0x7DBC,0x8074,0x8326,0x85D4,0x887C,0x8B1F,
  57. 0x8DBD,0x9055,0x92E8,0x9575,0x97FD,0x9A7F,0x9CFA,0x9F70,
  58. 0xA1E0,0xA44A,0xA6AD,0xA90A,0xAB60,0xADB0,0xAFF9,0xB23B,
  59. 0xB477,0xB6AC,0xB8DA,0xBB00,0xBD20,0xBF38,0xC149,0xC353,
  60. 0xC555,0xC74F,0xC942,0xCB2E,0xCD11,0xCEED,0xD0C0,0xD28C,
  61. 0xD450,0xD60B,0xD7BF,0xD96A,0xDB0D,0xDCA7,0xDE39,0xDFC2,
  62. 0xE143,0xE2BC,0xE42B,0xE592,0xE6F0,0xE845,0xE992,0xEAD5,
  63. 0xEC10,0xED41,0xEE6A,0xEF89,0xF09F,0xF1AC,0xF2AF,0xF3AA,
  64. 0xF49B,0xF582,0xF661,0xF736,0xF801,0xF8C3,0xF97B,0xFA2A,
  65. 0xFACF,0xFB6B,0xFBFD,0xFC86,0xFD04,0xFD7A,0xFDE5,0xFE47,
  66. 0xFE9F,0xFEED,0xFF31,0xFF6C,0xFF9D,0xFFC4,0xFFE1,0xFFF5,
  67. 0xFFFF
  68. };
  69. #endif
  70. void fft_256(s32 *buf);
  71. void ifft_256(s32* buf);
  72. void lock_code_alg(u32 start_addr, u32 end_addr);
  73. void unlock_code_alg(void);
  74. extern u32 __code_start_alg, __code_end_alg;
  75. typedef signed long long __int64;
  76. __int64 lo;
  77. #define MZR() do {(lo) = 0;} while(0)
  78. #define ML0(x, y) ((lo) = (__int64)(x) * (__int64)(y))
  79. #define MS0(x, y) ((lo) = -(__int64)(x) * (__int64)(y))
  80. #define MLA(x, y) ((lo) += (__int64)(x) * (__int64)(y))
  81. #define MSB(x, y) ((lo) -= (__int64)(x) * (__int64)(y))
  82. #define MLZ(n) (int)(((lo) + (1<<(n-1)))>>(n))
  83. #define round(x,n) ((int) ((x+(1<<(n-1)))>>n))
  84. #define MAC_LO() ((int *)(void *)&lo)[0]
  85. #define MAC_HI() ((int *)(void *)&lo)[1]
  86. #define MAC_SET_LO(x) do {((int *)(void *)&lo)[0] = x;} while(0)
  87. #define MAC_SET_HI(x) do {((int *)(void *)&lo)[1] = x;} while(0)
  88. #define AEC_SPL_SAT(A, B, C) (B > A ? A : B < C ? C : B)
  89. #define AEC_SPL_WORD16_MAX (32767)
  90. #define AEC_SPL_WORD16_MIN (-32768)
  91. ALWAYS_INLINE int aec_spl_sat(int x0)
  92. {
  93. int y0;
  94. __asm__ volatile("p.clip %0, %1, %2" : "=r"(y0) : "r"(x0), "i"(15));
  95. return y0;
  96. }
  97. AT(.ains4_text.alg)
  98. static void asr_kws_process(void)
  99. {
  100. int i;
  101. struct nr_buf_t *p = &nr_buf;
  102. for(i = 0; i < PART_LEN; i++) {
  103. p->xbuf[i + PART_LEN] = ains4_rdft.input[i];
  104. }
  105. for(i = 0; i < PART_LEN; i++) {
  106. ML0(p->xbuf[i], sqrt_Hanning[i]);
  107. p->fft[i] = MLZ(HANN_SHIFT);
  108. ML0(p->xbuf[PART_LEN + i], sqrt_Hanning[PART_LEN - i]);
  109. p->fft[PART_LEN + i] = MLZ(HANN_SHIFT);
  110. }
  111. fft_256((s32*)p->fft);
  112. ains4_mono_process((s32*)p->fft);
  113. ifft_256((s32*)p->fft);
  114. for(i = 0; i < PART_LEN; i++) {
  115. // Do we need saturation ?
  116. p->fft[i] = AEC_SPL_SAT(AEC_SPL_WORD16_MAX, p->fft[i], AEC_SPL_WORD16_MIN);
  117. ML0(p->fft[i], sqrt_Hanning[i]);
  118. p->fft[i] = MLZ(HANN_SHIFT)+p->outBuf[i];
  119. ains4_rdft.fft_output[i] = (short)AEC_SPL_SAT(AEC_SPL_WORD16_MAX, p->fft[i], AEC_SPL_WORD16_MIN);
  120. ML0(p->fft[PART_LEN + i], sqrt_Hanning[PART_LEN - i]);
  121. p->outBuf[i] = MLZ(HANN_SHIFT);
  122. }
  123. memcpy(p->xbuf, p->xbuf + PART_LEN, 2 * PART_LEN);
  124. }
  125. AT(.ains4_text.ains4)
  126. void ains4_process(s16 *buf)
  127. {
  128. for (int i = 0; i < PART_HALF_LEN; i++) {
  129. ains4_rdft.input[ains4_rdft.iptr * PART_HALF_LEN + i] = buf[i];
  130. }
  131. ains4_rdft.iptr++;
  132. if (ains4_rdft.iptr >= 2) {
  133. ains4_rdft.iptr = 0;
  134. memcpy(ains4_rdft.output, ains4_rdft.fft_output, PART_LEN * 2);
  135. asr_kws_process();
  136. ains4_rdft.optr = 0;
  137. }
  138. memcpy(buf, &ains4_rdft.output[ains4_rdft.optr * PART_HALF_LEN], PART_HALF_LEN * 2);
  139. ains4_rdft.optr++;
  140. if (ains4_rdft.optr >= 2) {
  141. ains4_rdft.optr = 0;
  142. }
  143. }
  144. AT(.text.ains4_init)
  145. void ains4_init(void)
  146. {
  147. if (ains4_cb.init == 0) {
  148. memset(&ains4_rdft, 0, sizeof(ains4_rdft_t));
  149. memset(&nr_buf, 0, sizeof(struct nr_buf_t));
  150. ains4_cb.sysclk = sys_clk_get_cur();
  151. printf("ains4_cb.sysclk:%d\n",ains4_cb.sysclk);
  152. if (ains4_cb.sysclk < SYS_160M) {
  153. sys_clk_set(SYS_160M);
  154. }
  155. ains4_rdft.optr = 1;
  156. // lock_code_alg((u32)&__code_start_alg, (u32)&__code_end_alg);
  157. ains4_mono_init(AINS4_NR_SUPPRESS, AINS4_PRIOR_OPT_IDX);
  158. ains4_cb.init = 1;
  159. }
  160. }
  161. AT(.text.ains4_exit)
  162. void ains4_exit(void)
  163. {
  164. if (ains4_cb.init) {
  165. ains4_cb.init = 0;
  166. // unlock_code_alg();
  167. sys_clk_set(ains4_cb.sysclk);
  168. }
  169. }
  170. #endif //(AINS4_EN)