asmtest.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4. #include "dsp_foo/mathevrc.h"
  5. #include "include/dsp_math.h"
  6. #define LOOP_COUNT 10000
  7. #define BIG_LOOP_COUNT 1000000
  8. static const INT16 s_vars[] = { 0,1,2,15,16,31,32,32766,32767,-1,-2,-15,-16,-31,-32,-32767,-32768};
  9. static const int l_vars[] = { 0,1,2,15,16,31,32,32766,32767,0x7FFFFFFE,0x7FFFFFFF,-1,-2,-15,-16,-31,-32,-32767,-32768,0x80000001,0x80000000 };
  10. static const INT16 us_vars[] = { 0,1,2,15,16,31,32,32766,32767};
  11. static UINT32 gettime_ms() {
  12. UINT32 ms = 0;
  13. struct timespec tv;
  14. clock_gettime(CLOCK_MONOTONIC,&tv);
  15. ms = (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
  16. return ms;
  17. }
  18. typedef Shortword (*tfunc_s_s)(Shortword);
  19. typedef Shortword (*tfunc_s_ss)(Shortword,Shortword);
  20. typedef Longword (*tfunc_l_l)(Longword);
  21. typedef Longword (*tfunc_l_ls)(Longword,Shortword);
  22. typedef Longword (*tfunc_l_ll)(Longword,Longword);
  23. typedef Shortword (*tfunc_s_l)(Longword);
  24. static int test_s_s(const char* name,tfunc_s_s f1,tfunc_s_s f2) {
  25. int i,k;
  26. UINT32 tv_start;
  27. INT16 svar1,sres1,sres2;
  28. printf("testing %s\n",name);
  29. for(i=0; i < sizeof(s_vars)/sizeof(INT16); ++i) {
  30. svar1 = s_vars[i];
  31. sres1 = (*f1)(svar1);
  32. sres2 = (*f2)(svar1);
  33. if( sres1 != sres2 ) {
  34. printf("%s(%hd) func1=%hd, func2=%hd\n",name,svar1,sres1,sres2);
  35. return -1;
  36. }
  37. }
  38. for(i=0;i < LOOP_COUNT; ++i) {
  39. svar1 = (INT16)(rand() & 0x0000FFFF);
  40. sres1 = (*f1)(svar1);
  41. sres2 = (*f2)(svar1);
  42. if( sres1 != sres2 ) {
  43. printf("%s(%hd) func1=%hd, func2=%hd\n",name,svar1,sres1,sres2);
  44. return -1;
  45. }
  46. }
  47. tv_start = gettime_ms();
  48. k = BIG_LOOP_COUNT;
  49. do {
  50. for(i=sizeof(s_vars)/sizeof(INT16); i && k; --i,--k) {
  51. sres1 = (*f2)(s_vars[i]);
  52. }
  53. } while(k);
  54. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  55. tv_start = gettime_ms();
  56. k = BIG_LOOP_COUNT;
  57. do {
  58. for(i=sizeof(s_vars)/sizeof(INT16); i && k; --i,--k) {
  59. sres1 = (*f1)(s_vars[i]);
  60. }
  61. } while(k);
  62. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  63. }
  64. static int test_s_ss(const char* name,tfunc_s_ss f1,tfunc_s_ss f2) {
  65. int i,j,k;
  66. INT16 svar1,svar2,sres1,sres2;
  67. UINT32 tv_start;
  68. printf("testing %s\n",name);
  69. for(i=0; i < sizeof(s_vars)/sizeof(INT16); ++i) {
  70. svar1 = s_vars[i];
  71. for(j=0; j < sizeof(s_vars)/sizeof(INT16); ++j) {
  72. svar2 = s_vars[j];
  73. sres1 = (*f1)(svar1,svar2);
  74. sres2 = (*f2)(svar1,svar2);
  75. if( sres1 != sres2 ) {
  76. printf("%s(%hd,%hd) func1=%hd, func2=%hd\n",name,svar1,svar2,sres1,sres2);
  77. return -1;
  78. }
  79. }
  80. }
  81. for(i=0;i < LOOP_COUNT; ++i) {
  82. svar1 = (INT16)(rand() & 0x0000FFFF);
  83. svar2 = (INT16)(rand() & 0x0000FFFF);
  84. sres1 = (*f1)(svar1,svar2);
  85. sres2 = (*f2)(svar1,svar2);
  86. if( sres1 != sres2 ) {
  87. printf("%s(%hd,%hd) func1=%hd, func2=%hd\n",name,svar1,svar2,sres1,sres2);
  88. return -1;
  89. }
  90. }
  91. tv_start = gettime_ms();
  92. k = BIG_LOOP_COUNT;
  93. do {
  94. for(i=sizeof(s_vars)/sizeof(INT16); i && k ; --i) {
  95. svar1 = s_vars[i];
  96. for(j=sizeof(s_vars)/sizeof(INT16); j && k ; --j,--k) {
  97. svar2 = s_vars[j];
  98. sres1 = (*f2)(svar1,svar2);
  99. }
  100. }
  101. } while( k != 0);
  102. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  103. tv_start = gettime_ms();
  104. k = BIG_LOOP_COUNT;
  105. do {
  106. for(i=sizeof(s_vars)/sizeof(INT16); i && k ; --i) {
  107. svar1 = s_vars[i];
  108. for(j=sizeof(s_vars)/sizeof(INT16); j && k ; --j,--k) {
  109. svar2 = s_vars[j];
  110. sres1 = (*f1)(svar1,svar2);
  111. }
  112. }
  113. } while( k != 0);
  114. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  115. }
  116. static int test_l_l(const char* name,tfunc_l_l f1,tfunc_l_l f2) {
  117. int i,k;
  118. UINT32 tv_start;
  119. int lvar1,lres1,lres2;
  120. printf("testing %s\n",name);
  121. for(i=0; i < sizeof(l_vars)/sizeof(int); ++i) {
  122. lvar1 = l_vars[i];
  123. lres1 = (*f1)(lvar1);
  124. lres2 = (*f2)(lvar1);
  125. if( lres1 != lres2 ) {
  126. printf("%s(%d) func1=%d, func2=%d\n",name,lvar1,lres1,lres2);
  127. return -1;
  128. }
  129. }
  130. for(i=0;i < LOOP_COUNT; ++i) {
  131. lvar1 = rand();
  132. lres1 = (*f1)(lvar1);
  133. lres2 = (*f2)(lvar1);
  134. if( lres1 != lres2 ) {
  135. printf("%s(%d) func1=%d, func2=%d\n",name,lvar1,lres1,lres2);
  136. return -1;
  137. }
  138. }
  139. tv_start = gettime_ms();
  140. k = BIG_LOOP_COUNT;
  141. do {
  142. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i,--k) {
  143. lvar1 = l_vars[i];
  144. lres1 = (*f2)(lvar1);
  145. }
  146. } while( k );
  147. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  148. tv_start = gettime_ms();
  149. k = BIG_LOOP_COUNT;
  150. do {
  151. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i,--k) {
  152. lvar1 = l_vars[i];
  153. lres1 = (*f1)(lvar1);
  154. }
  155. } while( k );
  156. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  157. }
  158. static int test_l_ls(const char* name,tfunc_l_ls f1,tfunc_l_ls f2) {
  159. int i,j,k;
  160. int lvar1,lres1,lres2;
  161. INT16 svar2;
  162. UINT32 tv_start;
  163. printf("testing %s\n",name);
  164. for(i=0; i < sizeof(l_vars)/sizeof(int); ++i) {
  165. lvar1 = l_vars[i];
  166. for(j=0; j < sizeof(s_vars)/sizeof(INT16); ++j) {
  167. svar2 = s_vars[j];
  168. lres1 = (*f1)(lvar1,svar2);
  169. lres2 = (*f2)(lvar1,svar2);
  170. if( lres1 != lres2 ) {
  171. printf("%s(%d,%hd) func1=%d, func2=%d\n",name,lvar1,svar2,lres1,lres2);
  172. return -1;
  173. }
  174. }
  175. }
  176. for(i=0;i < LOOP_COUNT; ++i) {
  177. lvar1 = rand();
  178. svar2 = (INT16)(rand() & 0x0000FFFF);
  179. lres1 = (*f1)(lvar1,svar2);
  180. lres2 = (*f2)(lvar1,svar2);
  181. if( lres1 != lres2 ) {
  182. printf("%s(%d,%hd) func1=%d, func2=%d\n",name,lvar1,svar2,lres1,lres2);
  183. return -1;
  184. }
  185. }
  186. tv_start = gettime_ms();
  187. k = BIG_LOOP_COUNT;
  188. do {
  189. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i) {
  190. lvar1 = l_vars[i];
  191. for(j=sizeof(s_vars)/sizeof(INT16); j && k ; --j,--k) {
  192. svar2 = s_vars[j];
  193. lres1 = (*f2)(lvar1,svar2);
  194. }
  195. }
  196. } while( k );
  197. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  198. tv_start = gettime_ms();
  199. k = BIG_LOOP_COUNT;
  200. do {
  201. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i) {
  202. lvar1 = l_vars[i];
  203. for(j=sizeof(s_vars)/sizeof(INT16); j && k ; --j,--k) {
  204. svar2 = s_vars[j];
  205. lres1 = (*f1)(lvar1,svar2);
  206. }
  207. }
  208. } while( k );
  209. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  210. }
  211. static int test_l_ll(const char* name,tfunc_l_ll f1,tfunc_l_ll f2) {
  212. int i,j,k;
  213. int lvar1,lvar2,lres1,lres2;
  214. UINT32 tv_start;
  215. printf("testing %s\n",name);
  216. for(i=0; i < sizeof(l_vars)/sizeof(int); ++i) {
  217. lvar1 = l_vars[i];
  218. for(j=0; j < sizeof(l_vars)/sizeof(int); ++j) {
  219. lvar2 = l_vars[j];
  220. lres1 = (*f1)(lvar1,lvar2);
  221. lres2 = (*f2)(lvar1,lvar2);
  222. if( lres1 != lres2 ) {
  223. printf("%s(%d,%d) func1=%d, func2=%d\n",name,lvar1,lvar2,lres1,lres2);
  224. return -1;
  225. }
  226. }
  227. }
  228. for(i=0;i < LOOP_COUNT; ++i) {
  229. lvar1 = rand();
  230. lvar2 = rand();
  231. lres1 = (*f1)(lvar1,lvar2);
  232. lres2 = (*f2)(lvar1,lvar2);
  233. if( lres1 != lres2 ) {
  234. printf("%s(%d,%d) func1=%d, func2=%d\n",name,lvar1,lvar2,lres1,lres2);
  235. return -1;
  236. }
  237. }
  238. tv_start = gettime_ms();
  239. k = BIG_LOOP_COUNT;
  240. do {
  241. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i) {
  242. lvar1 = l_vars[i];
  243. for(j=sizeof(l_vars)/sizeof(int); j && k ; --j,--k) {
  244. lvar2 = l_vars[j];
  245. lres1 = (*f2)(lvar1,lvar2);
  246. }
  247. }
  248. } while( k );
  249. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  250. tv_start = gettime_ms();
  251. k = BIG_LOOP_COUNT;
  252. do {
  253. for(i=sizeof(l_vars)/sizeof(int); i && k ; --i) {
  254. lvar1 = l_vars[i];
  255. for(j=sizeof(l_vars)/sizeof(int); j && k ; --j,--k) {
  256. lvar2 = l_vars[j];
  257. lres1 = (*f1)(lvar1,lvar2);
  258. }
  259. }
  260. } while( k );
  261. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  262. }
  263. static int test_s_l(const char* name,tfunc_s_l f1,tfunc_s_l f2) {
  264. int i,k;
  265. UINT32 tv_start;
  266. int lvar1;
  267. INT16 sres1,sres2;
  268. printf("testing %s\n",name);
  269. for(i=0; i < sizeof(l_vars)/sizeof(int); ++i) {
  270. lvar1 = l_vars[i];
  271. sres1 = (*f1)(lvar1);
  272. sres2 = (*f2)(lvar1);
  273. if( sres1 != sres2 ) {
  274. printf("%s(%d) func1=%hd, func2=%hd\n",name,lvar1,sres1,sres2);
  275. return -1;
  276. }
  277. }
  278. for(i=0;i < LOOP_COUNT; ++i) {
  279. lvar1 = rand();
  280. sres1 = (*f1)(lvar1);
  281. sres2 = (*f2)(lvar1);
  282. if( sres1 != sres2 ) {
  283. printf("%s(%d) func1=%hd, func2=%hd\n",name,lvar1,sres1,sres2);
  284. return -1;
  285. }
  286. }
  287. tv_start = gettime_ms();
  288. k = BIG_LOOP_COUNT;
  289. do {
  290. for(i=sizeof(l_vars)/sizeof(int); i && k; --i,--k) {
  291. sres1 = (*f2)(l_vars[i]);
  292. }
  293. } while(k);
  294. printf("func2 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  295. tv_start = gettime_ms();
  296. k = BIG_LOOP_COUNT;
  297. do {
  298. for(i=sizeof(l_vars)/sizeof(int); i && k; --i,--k) {
  299. sres1 = (*f1)(l_vars[i]);
  300. }
  301. } while(k);
  302. printf("func1 %s cost: %lu ms\n",name,gettime_ms() - tv_start);
  303. }
  304. int asm_test();
  305. void c_fft_foo(Shortword * farray_ptr, Shortword isign);
  306. int main(int argc,char** argv) {
  307. int i,j;
  308. UINT32 tv_start;
  309. short data[128];
  310. short seed[128];
  311. srand(time(NULL));
  312. for(i=0; i < 128; ++i) {
  313. seed[i] = (INT16)(rand() & 0x0000FFFF);
  314. }
  315. for(i=0; i < 128; ++i) {
  316. data[i] = seed[i];
  317. }
  318. i = 100000;
  319. tv_start = gettime_ms();
  320. do {
  321. c_fft_foo(data,0);
  322. --i;
  323. } while(i);
  324. printf("c fft cost: %lu ms\n",gettime_ms() - tv_start);
  325. printf("c fft:\n");
  326. for(i=0; i < 128; ++i) {
  327. printf("%hd\t",data[i]);
  328. }
  329. printf("\n");
  330. for(i=0; i < 128; ++i) {
  331. data[i] = seed[i];
  332. }
  333. i = 100000;
  334. tv_start = gettime_ms();
  335. do {
  336. c_fft(data,0);
  337. --i;
  338. } while(i);
  339. printf("neon fft cost: %lu ms\n",gettime_ms() - tv_start);
  340. printf("neon fft:\n");
  341. for(i=0; i < 128; ++i) {
  342. printf("%hd\t",data[i]);
  343. }
  344. printf("\n");
  345. return 0;
  346. test_s_s("abs_s",&foo_abs_s,&abs_s);
  347. test_s_s("negate",&foo_negate,&negate);
  348. test_s_s("norm_s",&foo_norm_s,&norm_s);
  349. test_l_l("L_abs",&foo_L_abs,&L_abs);
  350. test_l_l("L_negate",&foo_L_negate,&L_negate);
  351. test_s_l("round32",&foo_round32,&round32);
  352. test_s_l("norm_l",&foo_norm_l,&norm_l);
  353. test_s_ss("add",&foo_add,&add);
  354. test_s_ss("sub",&foo_sub,&sub);
  355. test_s_ss("mult",&foo_mult,&mult);
  356. test_s_ss("shr",&foo_shr,&shr);
  357. test_s_ss("shl",&foo_shl,&shl);
  358. test_s_ss("mult_r",&foo_mult_r,&mult_r);
  359. test_s_ss("divide_s",&foo_divide_s,&divide_s);
  360. test_s_ss("shift_r",&foo_shift_r,&shift_r);
  361. test_l_ls("L_shr",&foo_L_shr,&L_shr);
  362. test_l_ls("L_shl",&foo_L_shl,&L_shl);
  363. test_l_ls("L_shift_r",&foo_L_shift_r,&L_shift_r);
  364. test_l_ls("L_mpy_ls",&foo_L_mpy_ls,&L_mpy_ls);
  365. test_l_ll("L_add",&foo_L_add,&L_add);
  366. test_l_ll("L_sub",&foo_L_sub,&L_sub);
  367. test_l_ll("L_mpy_ll",&foo_L_mpy_ll,&L_mpy_ll);
  368. /*
  369. test_s_lss("msu_r",&foo_msu_r,&msu_r);
  370. test_s_lss("mac_r",&foo_mac_r,&mac_r);
  371. test_l_lss("L_mac",&foo_L_mac,&L_mac);
  372. test_l_lss("L_msu",&foo_L_msu,&L_msu);
  373. test_l_ss("L_mult",&foo_L_mult,L_mult);
  374. */
  375. printf("Test done!\n");
  376. return 0;
  377. }
  378. ////////////////////////////////
  379. // c_fft
  380. //
  381. #define SIZE 128
  382. #define SIZE_BY_TWO 64
  383. #define NUM_STAGE 6
  384. #define TRUE 1
  385. #define FALSE 0
  386. static Shortword phs_tbl[] =
  387. {
  388. 32767, 0, 32729, -1608, 32610, -3212, 32413, -4808,
  389. 32138, -6393, 31786, -7962, 31357, -9512, 30853, -11039,
  390. 30274, -12540, 29622, -14010, 28899, -15447, 28106, -16846,
  391. 27246, -18205, 26320, -19520, 25330, -20788, 24279, -22006,
  392. 23170, -23170, 22006, -24279, 20788, -25330, 19520, -26320,
  393. 18205, -27246, 16846, -28106, 15447, -28899, 14010, -29622,
  394. 12540, -30274, 11039, -30853, 9512, -31357, 7962, -31786,
  395. 6393, -32138, 4808, -32413, 3212, -32610, 1608, -32729,
  396. 0, -32768, -1608, -32729, -3212, -32610, -4808, -32413,
  397. -6393, -32138, -7962, -31786, -9512, -31357, -11039, -30853,
  398. -12540, -30274, -14010, -29622, -15447, -28899, -16846, -28106,
  399. -18205, -27246, -19520, -26320, -20788, -25330, -22006, -24279,
  400. -23170, -23170, -24279, -22006, -25330, -20788, -26320, -19520,
  401. -27246, -18205, -28106, -16846, -28899, -15447, -29622, -14010,
  402. -30274, -12540, -30853, -11039, -31357, -9512, -31786, -7962,
  403. -32138, -6393, -32413, -4808, -32610, -3212, -32729, -1608
  404. };
  405. static Shortword ii_table[] =
  406. {SIZE / 2, SIZE / 4, SIZE / 8, SIZE / 16, SIZE / 32, SIZE / 64};
  407. /* FFT/IFFT function for complex sequences */
  408. /*
  409. * The decimation-in-time complex FFT/IFFT is implemented below.
  410. * The input complex numbers are presented as real part followed by
  411. * imaginary part for each sample. The counters are therefore
  412. * incremented by two to access the complex valued samples.
  413. */
  414. void c_fft_foo(Shortword * farray_ptr, Shortword isign)
  415. {
  416. int idx;
  417. Shortword i, j, k, ii, jj, kk, ji, kj;
  418. Longword ftmp, ftmp_real, ftmp_imag;
  419. Shortword tmp, tmp1, tmp2;
  420. /* Rearrange the input array in bit reversed order */
  421. for (i = 0, j = 0; i < SIZE - 2; i = i + 2)
  422. {
  423. if (j > i)
  424. {
  425. ftmp = *(farray_ptr + i);
  426. *(farray_ptr + i) = *(farray_ptr + j);
  427. *(farray_ptr + j) = ftmp;
  428. ftmp = *(farray_ptr + i + 1);
  429. *(farray_ptr + i + 1) = *(farray_ptr + j + 1);
  430. *(farray_ptr + j + 1) = ftmp;
  431. }
  432. k = SIZE_BY_TWO;
  433. while (j >= k)
  434. {
  435. j = sub(j, k);
  436. k = shr(k, 1);
  437. }
  438. j += k;
  439. }
  440. /* The FFT part */
  441. if (isign == 1)
  442. {
  443. for (i = 0; i < NUM_STAGE; i++)
  444. { /* i is stage counter */
  445. jj = shl(2, i); /* FFT size */
  446. kk = shl(jj, 1); /* 2 * FFT size */
  447. ii = ii_table[i]; /* 2 * number of FFT's */
  448. //printf("Stage[%hd],jj=%hd kk=%hd ii=%hd\n",i,jj,kk,ii);
  449. for (j = 0; j < jj; j = j + 2)
  450. { /* j is sample counter */
  451. ji = j * ii; /* ji is phase table index */
  452. /*
  453. *if( i == 5 ) {
  454. *printf("j=%hd,ji=%hd(phs_tab=(%hd,%hd))\n",j,ji,phs_tbl[ji],phs_tbl[ji+1]);
  455. *}
  456. */
  457. for (k = j; k < SIZE; k = k + kk)
  458. { /* k is butterfly top */
  459. kj = add(k, jj); /* kj is butterfly bottom */
  460. //printf("bfly(%hd,%hd)\n",k,kj);
  461. /* Butterfly computations */
  462. ftmp_real = L_sub(L_mult(*(farray_ptr + kj), phs_tbl[ji]),
  463. L_mult(*(farray_ptr + kj + 1), phs_tbl[ji + 1]));
  464. ftmp_imag = L_add(L_mult(*(farray_ptr + kj + 1), phs_tbl[ji]),
  465. L_mult(*(farray_ptr + kj), phs_tbl[ji + 1]));
  466. tmp1 = round32(ftmp_real);
  467. tmp2 = round32(ftmp_imag);
  468. tmp = sub(*(farray_ptr + k), tmp1);
  469. *(farray_ptr + kj) = shr(tmp, 1);
  470. tmp = sub(*(farray_ptr + k + 1), tmp2);
  471. *(farray_ptr + kj + 1) = shr(tmp, 1);
  472. tmp = add(*(farray_ptr + k), tmp1);
  473. *(farray_ptr + k) = shr(tmp, 1);
  474. tmp = add(*(farray_ptr + k + 1), tmp2);
  475. *(farray_ptr + k + 1) = shr(tmp, 1);
  476. }
  477. }
  478. }
  479. /* The IFFT part */
  480. }
  481. else
  482. {
  483. for (i = 0; i < NUM_STAGE; i++)
  484. { /* i is stage counter */
  485. jj = shl(2, i); /* FFT size */
  486. kk = shl(jj, 1); /* 2 * FFT size */
  487. ii = ii_table[i]; /* 2 * number of FFT's */
  488. for (j = 0; j < jj; j = j + 2)
  489. { /* j is sample counter */
  490. ji = j * ii; /* ji is phase table index */
  491. for (k = j; k < SIZE; k = k + kk)
  492. { /* k is butterfly top */
  493. kj = add(k, jj); /* kj is butterfly bottom */
  494. /* Butterfly computations */
  495. ftmp_real = L_add(L_mult(*(farray_ptr + kj), phs_tbl[ji]),
  496. L_mult(*(farray_ptr + kj + 1), phs_tbl[ji + 1]));
  497. ftmp_imag = L_sub(L_mult(*(farray_ptr + kj + 1), phs_tbl[ji]),
  498. L_mult(*(farray_ptr + kj), phs_tbl[ji + 1]));
  499. tmp1 = round32(ftmp_real);
  500. tmp2 = round32(ftmp_imag);
  501. *(farray_ptr + kj) = sub(*(farray_ptr + k), tmp1);
  502. *(farray_ptr + kj + 1) = sub(*(farray_ptr + k + 1), tmp2);
  503. *(farray_ptr + k) = add(*(farray_ptr + k), tmp1);
  504. *(farray_ptr + k + 1) = add(*(farray_ptr + k + 1), tmp2);
  505. }
  506. }
  507. }
  508. }
  509. } /* end of c_fft () */