smallft.c 22 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
  5. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
  9. * by the XIPHOPHORUS Company http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function: *unnormalized* fft transform
  13. last mod: $Id: smallft.c,v 1.19 2003/10/08 05:12:37 jm Exp $
  14. ********************************************************************/
  15. /* FFT implementation from OggSquish, minus cosine transforms,
  16. * minus all but radix 2/4 case. In Vorbis we only need this
  17. * cut-down version.
  18. *
  19. * To do more than just power-of-two sized vectors, see the full
  20. * version I wrote for NetLib.
  21. *
  22. * Note that the packing is a little strange; rather than the FFT r/i
  23. * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,
  24. * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the
  25. * FORTRAN version
  26. */
  27. #ifdef HAVE_CONFIG_H
  28. #include "config.h"
  29. #endif
  30. #include <math.h>
  31. #include "smallft.h"
  32. #include "arch.h"
  33. #include "os_support.h"
  34. static void drfti1(int n, float *wa, int *ifac){
  35. static int ntryh[4] = { 4,2,3,5 };
  36. static float tpi = 6.28318530717958648f;
  37. float arg,argh,argld,fi;
  38. int ntry=0,i,j=-1;
  39. int k1, l1, l2, ib;
  40. int ld, ii, ip, is, nq, nr;
  41. int ido, ipm, nfm1;
  42. int nl=n;
  43. int nf=0;
  44. L101:
  45. j++;
  46. if (j < 4)
  47. ntry=ntryh[j];
  48. else
  49. ntry+=2;
  50. L104:
  51. nq=nl/ntry;
  52. nr=nl-ntry*nq;
  53. if (nr!=0) goto L101;
  54. nf++;
  55. ifac[nf+1]=ntry;
  56. nl=nq;
  57. if(ntry!=2)goto L107;
  58. if(nf==1)goto L107;
  59. for (i=1;i<nf;i++){
  60. ib=nf-i+1;
  61. ifac[ib+1]=ifac[ib];
  62. }
  63. ifac[2] = 2;
  64. L107:
  65. if(nl!=1)goto L104;
  66. ifac[0]=n;
  67. ifac[1]=nf;
  68. argh=tpi/n;
  69. is=0;
  70. nfm1=nf-1;
  71. l1=1;
  72. if(nfm1==0)return;
  73. for (k1=0;k1<nfm1;k1++){
  74. ip=ifac[k1+2];
  75. ld=0;
  76. l2=l1*ip;
  77. ido=n/l2;
  78. ipm=ip-1;
  79. for (j=0;j<ipm;j++){
  80. ld+=l1;
  81. i=is;
  82. argld=(float)ld*argh;
  83. fi=0.f;
  84. for (ii=2;ii<ido;ii+=2){
  85. fi+=1.f;
  86. arg=fi*argld;
  87. wa[i++]=cos(arg);
  88. wa[i++]=sin(arg);
  89. }
  90. is+=ido;
  91. }
  92. l1=l2;
  93. }
  94. }
  95. static void fdrffti(int n, float *wsave, int *ifac){
  96. if (n == 1) return;
  97. drfti1(n, wsave+n, ifac);
  98. }
  99. static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
  100. int i,k;
  101. float ti2,tr2;
  102. int t0,t1,t2,t3,t4,t5,t6;
  103. t1=0;
  104. t0=(t2=l1*ido);
  105. t3=ido<<1;
  106. for(k=0;k<l1;k++){
  107. ch[t1<<1]=cc[t1]+cc[t2];
  108. ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
  109. t1+=ido;
  110. t2+=ido;
  111. }
  112. if(ido<2)return;
  113. if(ido==2)goto L105;
  114. t1=0;
  115. t2=t0;
  116. for(k=0;k<l1;k++){
  117. t3=t2;
  118. t4=(t1<<1)+(ido<<1);
  119. t5=t1;
  120. t6=t1+t1;
  121. for(i=2;i<ido;i+=2){
  122. t3+=2;
  123. t4-=2;
  124. t5+=2;
  125. t6+=2;
  126. tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
  127. ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
  128. ch[t6]=cc[t5]+ti2;
  129. ch[t4]=ti2-cc[t5];
  130. ch[t6-1]=cc[t5-1]+tr2;
  131. ch[t4-1]=cc[t5-1]-tr2;
  132. }
  133. t1+=ido;
  134. t2+=ido;
  135. }
  136. if(ido%2==1)return;
  137. L105:
  138. t3=(t2=(t1=ido)-1);
  139. t2+=t0;
  140. for(k=0;k<l1;k++){
  141. ch[t1]=-cc[t2];
  142. ch[t1-1]=cc[t3];
  143. t1+=ido<<1;
  144. t2+=ido;
  145. t3+=ido;
  146. }
  147. }
  148. static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
  149. float *wa2,float *wa3){
  150. static float hsqt2 = .70710678118654752f;
  151. int i,k,t0,t1,t2,t3,t4,t5,t6;
  152. float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
  153. t0=l1*ido;
  154. t1=t0;
  155. t4=t1<<1;
  156. t2=t1+(t1<<1);
  157. t3=0;
  158. for(k=0;k<l1;k++){
  159. tr1=cc[t1]+cc[t2];
  160. tr2=cc[t3]+cc[t4];
  161. ch[t5=t3<<2]=tr1+tr2;
  162. ch[(ido<<2)+t5-1]=tr2-tr1;
  163. ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
  164. ch[t5]=cc[t2]-cc[t1];
  165. t1+=ido;
  166. t2+=ido;
  167. t3+=ido;
  168. t4+=ido;
  169. }
  170. if(ido<2)return;
  171. if(ido==2)goto L105;
  172. t1=0;
  173. for(k=0;k<l1;k++){
  174. t2=t1;
  175. t4=t1<<2;
  176. t5=(t6=ido<<1)+t4;
  177. for(i=2;i<ido;i+=2){
  178. t3=(t2+=2);
  179. t4+=2;
  180. t5-=2;
  181. t3+=t0;
  182. cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
  183. ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
  184. t3+=t0;
  185. cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
  186. ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
  187. t3+=t0;
  188. cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
  189. ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
  190. tr1=cr2+cr4;
  191. tr4=cr4-cr2;
  192. ti1=ci2+ci4;
  193. ti4=ci2-ci4;
  194. ti2=cc[t2]+ci3;
  195. ti3=cc[t2]-ci3;
  196. tr2=cc[t2-1]+cr3;
  197. tr3=cc[t2-1]-cr3;
  198. ch[t4-1]=tr1+tr2;
  199. ch[t4]=ti1+ti2;
  200. ch[t5-1]=tr3-ti4;
  201. ch[t5]=tr4-ti3;
  202. ch[t4+t6-1]=ti4+tr3;
  203. ch[t4+t6]=tr4+ti3;
  204. ch[t5+t6-1]=tr2-tr1;
  205. ch[t5+t6]=ti1-ti2;
  206. }
  207. t1+=ido;
  208. }
  209. if(ido&1)return;
  210. L105:
  211. t2=(t1=t0+ido-1)+(t0<<1);
  212. t3=ido<<2;
  213. t4=ido;
  214. t5=ido<<1;
  215. t6=ido;
  216. for(k=0;k<l1;k++){
  217. ti1=-hsqt2*(cc[t1]+cc[t2]);
  218. tr1=hsqt2*(cc[t1]-cc[t2]);
  219. ch[t4-1]=tr1+cc[t6-1];
  220. ch[t4+t5-1]=cc[t6-1]-tr1;
  221. ch[t4]=ti1-cc[t1+t0];
  222. ch[t4+t5]=ti1+cc[t1+t0];
  223. t1+=ido;
  224. t2+=ido;
  225. t4+=t3;
  226. t6+=ido;
  227. }
  228. }
  229. static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
  230. float *c2,float *ch,float *ch2,float *wa){
  231. static float tpi=6.283185307179586f;
  232. int idij,ipph,i,j,k,l,ic,ik,is;
  233. int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
  234. float dc2,ai1,ai2,ar1,ar2,ds2;
  235. int nbd;
  236. float dcp,arg,dsp,ar1h,ar2h;
  237. int idp2,ipp2;
  238. arg=tpi/(float)ip;
  239. dcp=cos(arg);
  240. dsp=sin(arg);
  241. ipph=(ip+1)>>1;
  242. ipp2=ip;
  243. idp2=ido;
  244. nbd=(ido-1)>>1;
  245. t0=l1*ido;
  246. t10=ip*ido;
  247. if(ido==1)goto L119;
  248. for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
  249. t1=0;
  250. for(j=1;j<ip;j++){
  251. t1+=t0;
  252. t2=t1;
  253. for(k=0;k<l1;k++){
  254. ch[t2]=c1[t2];
  255. t2+=ido;
  256. }
  257. }
  258. is=-ido;
  259. t1=0;
  260. if(nbd>l1){
  261. for(j=1;j<ip;j++){
  262. t1+=t0;
  263. is+=ido;
  264. t2= -ido+t1;
  265. for(k=0;k<l1;k++){
  266. idij=is-1;
  267. t2+=ido;
  268. t3=t2;
  269. for(i=2;i<ido;i+=2){
  270. idij+=2;
  271. t3+=2;
  272. ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
  273. ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
  274. }
  275. }
  276. }
  277. }else{
  278. for(j=1;j<ip;j++){
  279. is+=ido;
  280. idij=is-1;
  281. t1+=t0;
  282. t2=t1;
  283. for(i=2;i<ido;i+=2){
  284. idij+=2;
  285. t2+=2;
  286. t3=t2;
  287. for(k=0;k<l1;k++){
  288. ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
  289. ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
  290. t3+=ido;
  291. }
  292. }
  293. }
  294. }
  295. t1=0;
  296. t2=ipp2*t0;
  297. if(nbd<l1){
  298. for(j=1;j<ipph;j++){
  299. t1+=t0;
  300. t2-=t0;
  301. t3=t1;
  302. t4=t2;
  303. for(i=2;i<ido;i+=2){
  304. t3+=2;
  305. t4+=2;
  306. t5=t3-ido;
  307. t6=t4-ido;
  308. for(k=0;k<l1;k++){
  309. t5+=ido;
  310. t6+=ido;
  311. c1[t5-1]=ch[t5-1]+ch[t6-1];
  312. c1[t6-1]=ch[t5]-ch[t6];
  313. c1[t5]=ch[t5]+ch[t6];
  314. c1[t6]=ch[t6-1]-ch[t5-1];
  315. }
  316. }
  317. }
  318. }else{
  319. for(j=1;j<ipph;j++){
  320. t1+=t0;
  321. t2-=t0;
  322. t3=t1;
  323. t4=t2;
  324. for(k=0;k<l1;k++){
  325. t5=t3;
  326. t6=t4;
  327. for(i=2;i<ido;i+=2){
  328. t5+=2;
  329. t6+=2;
  330. c1[t5-1]=ch[t5-1]+ch[t6-1];
  331. c1[t6-1]=ch[t5]-ch[t6];
  332. c1[t5]=ch[t5]+ch[t6];
  333. c1[t6]=ch[t6-1]-ch[t5-1];
  334. }
  335. t3+=ido;
  336. t4+=ido;
  337. }
  338. }
  339. }
  340. L119:
  341. for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
  342. t1=0;
  343. t2=ipp2*idl1;
  344. for(j=1;j<ipph;j++){
  345. t1+=t0;
  346. t2-=t0;
  347. t3=t1-ido;
  348. t4=t2-ido;
  349. for(k=0;k<l1;k++){
  350. t3+=ido;
  351. t4+=ido;
  352. c1[t3]=ch[t3]+ch[t4];
  353. c1[t4]=ch[t4]-ch[t3];
  354. }
  355. }
  356. ar1=1.f;
  357. ai1=0.f;
  358. t1=0;
  359. t2=ipp2*idl1;
  360. t3=(ip-1)*idl1;
  361. for(l=1;l<ipph;l++){
  362. t1+=idl1;
  363. t2-=idl1;
  364. ar1h=dcp*ar1-dsp*ai1;
  365. ai1=dcp*ai1+dsp*ar1;
  366. ar1=ar1h;
  367. t4=t1;
  368. t5=t2;
  369. t6=t3;
  370. t7=idl1;
  371. for(ik=0;ik<idl1;ik++){
  372. ch2[t4++]=c2[ik]+ar1*c2[t7++];
  373. ch2[t5++]=ai1*c2[t6++];
  374. }
  375. dc2=ar1;
  376. ds2=ai1;
  377. ar2=ar1;
  378. ai2=ai1;
  379. t4=idl1;
  380. t5=(ipp2-1)*idl1;
  381. for(j=2;j<ipph;j++){
  382. t4+=idl1;
  383. t5-=idl1;
  384. ar2h=dc2*ar2-ds2*ai2;
  385. ai2=dc2*ai2+ds2*ar2;
  386. ar2=ar2h;
  387. t6=t1;
  388. t7=t2;
  389. t8=t4;
  390. t9=t5;
  391. for(ik=0;ik<idl1;ik++){
  392. ch2[t6++]+=ar2*c2[t8++];
  393. ch2[t7++]+=ai2*c2[t9++];
  394. }
  395. }
  396. }
  397. t1=0;
  398. for(j=1;j<ipph;j++){
  399. t1+=idl1;
  400. t2=t1;
  401. for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
  402. }
  403. if(ido<l1)goto L132;
  404. t1=0;
  405. t2=0;
  406. for(k=0;k<l1;k++){
  407. t3=t1;
  408. t4=t2;
  409. for(i=0;i<ido;i++)cc[t4++]=ch[t3++];
  410. t1+=ido;
  411. t2+=t10;
  412. }
  413. goto L135;
  414. L132:
  415. for(i=0;i<ido;i++){
  416. t1=i;
  417. t2=i;
  418. for(k=0;k<l1;k++){
  419. cc[t2]=ch[t1];
  420. t1+=ido;
  421. t2+=t10;
  422. }
  423. }
  424. L135:
  425. t1=0;
  426. t2=ido<<1;
  427. t3=0;
  428. t4=ipp2*t0;
  429. for(j=1;j<ipph;j++){
  430. t1+=t2;
  431. t3+=t0;
  432. t4-=t0;
  433. t5=t1;
  434. t6=t3;
  435. t7=t4;
  436. for(k=0;k<l1;k++){
  437. cc[t5-1]=ch[t6];
  438. cc[t5]=ch[t7];
  439. t5+=t10;
  440. t6+=ido;
  441. t7+=ido;
  442. }
  443. }
  444. if(ido==1)return;
  445. if(nbd<l1)goto L141;
  446. t1=-ido;
  447. t3=0;
  448. t4=0;
  449. t5=ipp2*t0;
  450. for(j=1;j<ipph;j++){
  451. t1+=t2;
  452. t3+=t2;
  453. t4+=t0;
  454. t5-=t0;
  455. t6=t1;
  456. t7=t3;
  457. t8=t4;
  458. t9=t5;
  459. for(k=0;k<l1;k++){
  460. for(i=2;i<ido;i+=2){
  461. ic=idp2-i;
  462. cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
  463. cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
  464. cc[i+t7]=ch[i+t8]+ch[i+t9];
  465. cc[ic+t6]=ch[i+t9]-ch[i+t8];
  466. }
  467. t6+=t10;
  468. t7+=t10;
  469. t8+=ido;
  470. t9+=ido;
  471. }
  472. }
  473. return;
  474. L141:
  475. t1=-ido;
  476. t3=0;
  477. t4=0;
  478. t5=ipp2*t0;
  479. for(j=1;j<ipph;j++){
  480. t1+=t2;
  481. t3+=t2;
  482. t4+=t0;
  483. t5-=t0;
  484. for(i=2;i<ido;i+=2){
  485. t6=idp2+t1-i;
  486. t7=i+t3;
  487. t8=i+t4;
  488. t9=i+t5;
  489. for(k=0;k<l1;k++){
  490. cc[t7-1]=ch[t8-1]+ch[t9-1];
  491. cc[t6-1]=ch[t8-1]-ch[t9-1];
  492. cc[t7]=ch[t8]+ch[t9];
  493. cc[t6]=ch[t9]-ch[t8];
  494. t6+=t10;
  495. t7+=t10;
  496. t8+=ido;
  497. t9+=ido;
  498. }
  499. }
  500. }
  501. }
  502. static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
  503. int i,k1,l1,l2;
  504. int na,kh,nf;
  505. int ip,iw,ido,idl1,ix2,ix3;
  506. nf=ifac[1];
  507. na=1;
  508. l2=n;
  509. iw=n;
  510. for(k1=0;k1<nf;k1++){
  511. kh=nf-k1;
  512. ip=ifac[kh+1];
  513. l1=l2/ip;
  514. ido=n/l2;
  515. idl1=ido*l1;
  516. iw-=(ip-1)*ido;
  517. na=1-na;
  518. if(ip!=4)goto L102;
  519. ix2=iw+ido;
  520. ix3=ix2+ido;
  521. if(na!=0)
  522. dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
  523. else
  524. dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
  525. goto L110;
  526. L102:
  527. if(ip!=2)goto L104;
  528. if(na!=0)goto L103;
  529. dradf2(ido,l1,c,ch,wa+iw-1);
  530. goto L110;
  531. L103:
  532. dradf2(ido,l1,ch,c,wa+iw-1);
  533. goto L110;
  534. L104:
  535. if(ido==1)na=1-na;
  536. if(na!=0)goto L109;
  537. dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
  538. na=1;
  539. goto L110;
  540. L109:
  541. dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
  542. na=0;
  543. L110:
  544. l2=l1;
  545. }
  546. if(na==1)return;
  547. for(i=0;i<n;i++)c[i]=ch[i];
  548. }
  549. static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
  550. int i,k,t0,t1,t2,t3,t4,t5,t6;
  551. float ti2,tr2;
  552. t0=l1*ido;
  553. t1=0;
  554. t2=0;
  555. t3=(ido<<1)-1;
  556. for(k=0;k<l1;k++){
  557. ch[t1]=cc[t2]+cc[t3+t2];
  558. ch[t1+t0]=cc[t2]-cc[t3+t2];
  559. t2=(t1+=ido)<<1;
  560. }
  561. if(ido<2)return;
  562. if(ido==2)goto L105;
  563. t1=0;
  564. t2=0;
  565. for(k=0;k<l1;k++){
  566. t3=t1;
  567. t5=(t4=t2)+(ido<<1);
  568. t6=t0+t1;
  569. for(i=2;i<ido;i+=2){
  570. t3+=2;
  571. t4+=2;
  572. t5-=2;
  573. t6+=2;
  574. ch[t3-1]=cc[t4-1]+cc[t5-1];
  575. tr2=cc[t4-1]-cc[t5-1];
  576. ch[t3]=cc[t4]-cc[t5];
  577. ti2=cc[t4]+cc[t5];
  578. ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
  579. ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
  580. }
  581. t2=(t1+=ido)<<1;
  582. }
  583. if(ido%2==1)return;
  584. L105:
  585. t1=ido-1;
  586. t2=ido-1;
  587. for(k=0;k<l1;k++){
  588. ch[t1]=cc[t2]+cc[t2];
  589. ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
  590. t1+=ido;
  591. t2+=ido<<1;
  592. }
  593. }
  594. static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
  595. float *wa2){
  596. static float taur = -.5f;
  597. static float taui = .8660254037844386f;
  598. int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
  599. float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
  600. t0=l1*ido;
  601. t1=0;
  602. t2=t0<<1;
  603. t3=ido<<1;
  604. t4=ido+(ido<<1);
  605. t5=0;
  606. for(k=0;k<l1;k++){
  607. tr2=cc[t3-1]+cc[t3-1];
  608. cr2=cc[t5]+(taur*tr2);
  609. ch[t1]=cc[t5]+tr2;
  610. ci3=taui*(cc[t3]+cc[t3]);
  611. ch[t1+t0]=cr2-ci3;
  612. ch[t1+t2]=cr2+ci3;
  613. t1+=ido;
  614. t3+=t4;
  615. t5+=t4;
  616. }
  617. if(ido==1)return;
  618. t1=0;
  619. t3=ido<<1;
  620. for(k=0;k<l1;k++){
  621. t7=t1+(t1<<1);
  622. t6=(t5=t7+t3);
  623. t8=t1;
  624. t10=(t9=t1+t0)+t0;
  625. for(i=2;i<ido;i+=2){
  626. t5+=2;
  627. t6-=2;
  628. t7+=2;
  629. t8+=2;
  630. t9+=2;
  631. t10+=2;
  632. tr2=cc[t5-1]+cc[t6-1];
  633. cr2=cc[t7-1]+(taur*tr2);
  634. ch[t8-1]=cc[t7-1]+tr2;
  635. ti2=cc[t5]-cc[t6];
  636. ci2=cc[t7]+(taur*ti2);
  637. ch[t8]=cc[t7]+ti2;
  638. cr3=taui*(cc[t5-1]-cc[t6-1]);
  639. ci3=taui*(cc[t5]+cc[t6]);
  640. dr2=cr2-ci3;
  641. dr3=cr2+ci3;
  642. di2=ci2+cr3;
  643. di3=ci2-cr3;
  644. ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
  645. ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
  646. ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
  647. ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
  648. }
  649. t1+=ido;
  650. }
  651. }
  652. static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
  653. float *wa2,float *wa3){
  654. static float sqrt2=1.414213562373095f;
  655. int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
  656. float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
  657. t0=l1*ido;
  658. t1=0;
  659. t2=ido<<2;
  660. t3=0;
  661. t6=ido<<1;
  662. for(k=0;k<l1;k++){
  663. t4=t3+t6;
  664. t5=t1;
  665. tr3=cc[t4-1]+cc[t4-1];
  666. tr4=cc[t4]+cc[t4];
  667. tr1=cc[t3]-cc[(t4+=t6)-1];
  668. tr2=cc[t3]+cc[t4-1];
  669. ch[t5]=tr2+tr3;
  670. ch[t5+=t0]=tr1-tr4;
  671. ch[t5+=t0]=tr2-tr3;
  672. ch[t5+=t0]=tr1+tr4;
  673. t1+=ido;
  674. t3+=t2;
  675. }
  676. if(ido<2)return;
  677. if(ido==2)goto L105;
  678. t1=0;
  679. for(k=0;k<l1;k++){
  680. t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
  681. t7=t1;
  682. for(i=2;i<ido;i+=2){
  683. t2+=2;
  684. t3+=2;
  685. t4-=2;
  686. t5-=2;
  687. t7+=2;
  688. ti1=cc[t2]+cc[t5];
  689. ti2=cc[t2]-cc[t5];
  690. ti3=cc[t3]-cc[t4];
  691. tr4=cc[t3]+cc[t4];
  692. tr1=cc[t2-1]-cc[t5-1];
  693. tr2=cc[t2-1]+cc[t5-1];
  694. ti4=cc[t3-1]-cc[t4-1];
  695. tr3=cc[t3-1]+cc[t4-1];
  696. ch[t7-1]=tr2+tr3;
  697. cr3=tr2-tr3;
  698. ch[t7]=ti2+ti3;
  699. ci3=ti2-ti3;
  700. cr2=tr1-tr4;
  701. cr4=tr1+tr4;
  702. ci2=ti1+ti4;
  703. ci4=ti1-ti4;
  704. ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
  705. ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
  706. ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
  707. ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
  708. ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
  709. ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
  710. }
  711. t1+=ido;
  712. }
  713. if(ido%2 == 1)return;
  714. L105:
  715. t1=ido;
  716. t2=ido<<2;
  717. t3=ido-1;
  718. t4=ido+(ido<<1);
  719. for(k=0;k<l1;k++){
  720. t5=t3;
  721. ti1=cc[t1]+cc[t4];
  722. ti2=cc[t4]-cc[t1];
  723. tr1=cc[t1-1]-cc[t4-1];
  724. tr2=cc[t1-1]+cc[t4-1];
  725. ch[t5]=tr2+tr2;
  726. ch[t5+=t0]=sqrt2*(tr1-ti1);
  727. ch[t5+=t0]=ti2+ti2;
  728. ch[t5+=t0]=-sqrt2*(tr1+ti1);
  729. t3+=ido;
  730. t1+=t2;
  731. t4+=t2;
  732. }
  733. }
  734. static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
  735. float *c2,float *ch,float *ch2,float *wa){
  736. static float tpi=6.283185307179586f;
  737. int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
  738. t11,t12;
  739. float dc2,ai1,ai2,ar1,ar2,ds2;
  740. int nbd;
  741. float dcp,arg,dsp,ar1h,ar2h;
  742. int ipp2;
  743. t10=ip*ido;
  744. t0=l1*ido;
  745. arg=tpi/(float)ip;
  746. dcp=cos(arg);
  747. dsp=sin(arg);
  748. nbd=(ido-1)>>1;
  749. ipp2=ip;
  750. ipph=(ip+1)>>1;
  751. if(ido<l1)goto L103;
  752. t1=0;
  753. t2=0;
  754. for(k=0;k<l1;k++){
  755. t3=t1;
  756. t4=t2;
  757. for(i=0;i<ido;i++){
  758. ch[t3]=cc[t4];
  759. t3++;
  760. t4++;
  761. }
  762. t1+=ido;
  763. t2+=t10;
  764. }
  765. goto L106;
  766. L103:
  767. t1=0;
  768. for(i=0;i<ido;i++){
  769. t2=t1;
  770. t3=t1;
  771. for(k=0;k<l1;k++){
  772. ch[t2]=cc[t3];
  773. t2+=ido;
  774. t3+=t10;
  775. }
  776. t1++;
  777. }
  778. L106:
  779. t1=0;
  780. t2=ipp2*t0;
  781. t7=(t5=ido<<1);
  782. for(j=1;j<ipph;j++){
  783. t1+=t0;
  784. t2-=t0;
  785. t3=t1;
  786. t4=t2;
  787. t6=t5;
  788. for(k=0;k<l1;k++){
  789. ch[t3]=cc[t6-1]+cc[t6-1];
  790. ch[t4]=cc[t6]+cc[t6];
  791. t3+=ido;
  792. t4+=ido;
  793. t6+=t10;
  794. }
  795. t5+=t7;
  796. }
  797. if (ido == 1)goto L116;
  798. if(nbd<l1)goto L112;
  799. t1=0;
  800. t2=ipp2*t0;
  801. t7=0;
  802. for(j=1;j<ipph;j++){
  803. t1+=t0;
  804. t2-=t0;
  805. t3=t1;
  806. t4=t2;
  807. t7+=(ido<<1);
  808. t8=t7;
  809. for(k=0;k<l1;k++){
  810. t5=t3;
  811. t6=t4;
  812. t9=t8;
  813. t11=t8;
  814. for(i=2;i<ido;i+=2){
  815. t5+=2;
  816. t6+=2;
  817. t9+=2;
  818. t11-=2;
  819. ch[t5-1]=cc[t9-1]+cc[t11-1];
  820. ch[t6-1]=cc[t9-1]-cc[t11-1];
  821. ch[t5]=cc[t9]-cc[t11];
  822. ch[t6]=cc[t9]+cc[t11];
  823. }
  824. t3+=ido;
  825. t4+=ido;
  826. t8+=t10;
  827. }
  828. }
  829. goto L116;
  830. L112:
  831. t1=0;
  832. t2=ipp2*t0;
  833. t7=0;
  834. for(j=1;j<ipph;j++){
  835. t1+=t0;
  836. t2-=t0;
  837. t3=t1;
  838. t4=t2;
  839. t7+=(ido<<1);
  840. t8=t7;
  841. t9=t7;
  842. for(i=2;i<ido;i+=2){
  843. t3+=2;
  844. t4+=2;
  845. t8+=2;
  846. t9-=2;
  847. t5=t3;
  848. t6=t4;
  849. t11=t8;
  850. t12=t9;
  851. for(k=0;k<l1;k++){
  852. ch[t5-1]=cc[t11-1]+cc[t12-1];
  853. ch[t6-1]=cc[t11-1]-cc[t12-1];
  854. ch[t5]=cc[t11]-cc[t12];
  855. ch[t6]=cc[t11]+cc[t12];
  856. t5+=ido;
  857. t6+=ido;
  858. t11+=t10;
  859. t12+=t10;
  860. }
  861. }
  862. }
  863. L116:
  864. ar1=1.f;
  865. ai1=0.f;
  866. t1=0;
  867. t9=(t2=ipp2*idl1);
  868. t3=(ip-1)*idl1;
  869. for(l=1;l<ipph;l++){
  870. t1+=idl1;
  871. t2-=idl1;
  872. ar1h=dcp*ar1-dsp*ai1;
  873. ai1=dcp*ai1+dsp*ar1;
  874. ar1=ar1h;
  875. t4=t1;
  876. t5=t2;
  877. t6=0;
  878. t7=idl1;
  879. t8=t3;
  880. for(ik=0;ik<idl1;ik++){
  881. c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
  882. c2[t5++]=ai1*ch2[t8++];
  883. }
  884. dc2=ar1;
  885. ds2=ai1;
  886. ar2=ar1;
  887. ai2=ai1;
  888. t6=idl1;
  889. t7=t9-idl1;
  890. for(j=2;j<ipph;j++){
  891. t6+=idl1;
  892. t7-=idl1;
  893. ar2h=dc2*ar2-ds2*ai2;
  894. ai2=dc2*ai2+ds2*ar2;
  895. ar2=ar2h;
  896. t4=t1;
  897. t5=t2;
  898. t11=t6;
  899. t12=t7;
  900. for(ik=0;ik<idl1;ik++){
  901. c2[t4++]+=ar2*ch2[t11++];
  902. c2[t5++]+=ai2*ch2[t12++];
  903. }
  904. }
  905. }
  906. t1=0;
  907. for(j=1;j<ipph;j++){
  908. t1+=idl1;
  909. t2=t1;
  910. for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
  911. }
  912. t1=0;
  913. t2=ipp2*t0;
  914. for(j=1;j<ipph;j++){
  915. t1+=t0;
  916. t2-=t0;
  917. t3=t1;
  918. t4=t2;
  919. for(k=0;k<l1;k++){
  920. ch[t3]=c1[t3]-c1[t4];
  921. ch[t4]=c1[t3]+c1[t4];
  922. t3+=ido;
  923. t4+=ido;
  924. }
  925. }
  926. if(ido==1)goto L132;
  927. if(nbd<l1)goto L128;
  928. t1=0;
  929. t2=ipp2*t0;
  930. for(j=1;j<ipph;j++){
  931. t1+=t0;
  932. t2-=t0;
  933. t3=t1;
  934. t4=t2;
  935. for(k=0;k<l1;k++){
  936. t5=t3;
  937. t6=t4;
  938. for(i=2;i<ido;i+=2){
  939. t5+=2;
  940. t6+=2;
  941. ch[t5-1]=c1[t5-1]-c1[t6];
  942. ch[t6-1]=c1[t5-1]+c1[t6];
  943. ch[t5]=c1[t5]+c1[t6-1];
  944. ch[t6]=c1[t5]-c1[t6-1];
  945. }
  946. t3+=ido;
  947. t4+=ido;
  948. }
  949. }
  950. goto L132;
  951. L128:
  952. t1=0;
  953. t2=ipp2*t0;
  954. for(j=1;j<ipph;j++){
  955. t1+=t0;
  956. t2-=t0;
  957. t3=t1;
  958. t4=t2;
  959. for(i=2;i<ido;i+=2){
  960. t3+=2;
  961. t4+=2;
  962. t5=t3;
  963. t6=t4;
  964. for(k=0;k<l1;k++){
  965. ch[t5-1]=c1[t5-1]-c1[t6];
  966. ch[t6-1]=c1[t5-1]+c1[t6];
  967. ch[t5]=c1[t5]+c1[t6-1];
  968. ch[t6]=c1[t5]-c1[t6-1];
  969. t5+=ido;
  970. t6+=ido;
  971. }
  972. }
  973. }
  974. L132:
  975. if(ido==1)return;
  976. for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
  977. t1=0;
  978. for(j=1;j<ip;j++){
  979. t2=(t1+=t0);
  980. for(k=0;k<l1;k++){
  981. c1[t2]=ch[t2];
  982. t2+=ido;
  983. }
  984. }
  985. if(nbd>l1)goto L139;
  986. is= -ido-1;
  987. t1=0;
  988. for(j=1;j<ip;j++){
  989. is+=ido;
  990. t1+=t0;
  991. idij=is;
  992. t2=t1;
  993. for(i=2;i<ido;i+=2){
  994. t2+=2;
  995. idij+=2;
  996. t3=t2;
  997. for(k=0;k<l1;k++){
  998. c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
  999. c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
  1000. t3+=ido;
  1001. }
  1002. }
  1003. }
  1004. return;
  1005. L139:
  1006. is= -ido-1;
  1007. t1=0;
  1008. for(j=1;j<ip;j++){
  1009. is+=ido;
  1010. t1+=t0;
  1011. t2=t1;
  1012. for(k=0;k<l1;k++){
  1013. idij=is;
  1014. t3=t2;
  1015. for(i=2;i<ido;i+=2){
  1016. idij+=2;
  1017. t3+=2;
  1018. c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
  1019. c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
  1020. }
  1021. t2+=ido;
  1022. }
  1023. }
  1024. }
  1025. static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
  1026. int i,k1,l1,l2;
  1027. int na;
  1028. int nf,ip,iw,ix2,ix3,ido,idl1;
  1029. nf=ifac[1];
  1030. na=0;
  1031. l1=1;
  1032. iw=1;
  1033. for(k1=0;k1<nf;k1++){
  1034. ip=ifac[k1 + 2];
  1035. l2=ip*l1;
  1036. ido=n/l2;
  1037. idl1=ido*l1;
  1038. if(ip!=4)goto L103;
  1039. ix2=iw+ido;
  1040. ix3=ix2+ido;
  1041. if(na!=0)
  1042. dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
  1043. else
  1044. dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
  1045. na=1-na;
  1046. goto L115;
  1047. L103:
  1048. if(ip!=2)goto L106;
  1049. if(na!=0)
  1050. dradb2(ido,l1,ch,c,wa+iw-1);
  1051. else
  1052. dradb2(ido,l1,c,ch,wa+iw-1);
  1053. na=1-na;
  1054. goto L115;
  1055. L106:
  1056. if(ip!=3)goto L109;
  1057. ix2=iw+ido;
  1058. if(na!=0)
  1059. dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
  1060. else
  1061. dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
  1062. na=1-na;
  1063. goto L115;
  1064. L109:
  1065. /* The radix five case can be translated later..... */
  1066. /* if(ip!=5)goto L112;
  1067. ix2=iw+ido;
  1068. ix3=ix2+ido;
  1069. ix4=ix3+ido;
  1070. if(na!=0)
  1071. dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
  1072. else
  1073. dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
  1074. na=1-na;
  1075. goto L115;
  1076. L112:*/
  1077. if(na!=0)
  1078. dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
  1079. else
  1080. dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
  1081. if(ido==1)na=1-na;
  1082. L115:
  1083. l1=l2;
  1084. iw+=(ip-1)*ido;
  1085. }
  1086. if(na==0)return;
  1087. for(i=0;i<n;i++)c[i]=ch[i];
  1088. }
  1089. void spx_drft_forward(struct drft_lookup *l,float *data){
  1090. if(l->n==1)return;
  1091. drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
  1092. }
  1093. void spx_drft_backward(struct drft_lookup *l,float *data){
  1094. if (l->n==1)return;
  1095. drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
  1096. }
  1097. void spx_drft_init(struct drft_lookup *l,int n)
  1098. {
  1099. l->n=n;
  1100. l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache));
  1101. l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache));
  1102. fdrffti(n, l->trigcache, l->splitcache);
  1103. }
  1104. void spx_drft_clear(struct drft_lookup *l)
  1105. {
  1106. if(l)
  1107. {
  1108. if(l->trigcache)
  1109. speex_free(l->trigcache);
  1110. if(l->splitcache)
  1111. speex_free(l->splitcache);
  1112. }
  1113. }