smallft.c 22 KB

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