mdct.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
  6. * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
  9. * by Monty <monty@xiph.org> and the XIPHOPHORUS Company *
  10. * http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: normalized modified discrete cosine transform
  14. power of two length transform only [16 <= n ]
  15. last mod: $Id: mdct.c,v 1.17.2.5 2000/11/04 06:43:50 xiphmont Exp $
  16. Algorithm adapted from _The use of multirate filter banks for coding
  17. of high quality digital audio_, by T. Sporer, K. Brandenburg and
  18. B. Edler, collection of the European Signal Processing Conference
  19. (EUSIPCO), Amsterdam, June 1992, Vol.1, pp 211-214
  20. Note that the below code won't make much sense without the paper;
  21. The presented algorithm was already fairly polished, and the code
  22. once followed it closely. The current code both corrects several
  23. typos in the paper and goes beyond the presented optimizations
  24. (steps 4 through 6 are, for example, entirely eliminated).
  25. This module DOES NOT INCLUDE code to generate the window function.
  26. Everybody has their own weird favorite including me... I happen to
  27. like the properties of y=sin(2PI*sin^2(x)), but others may vehemently
  28. disagree.
  29. ********************************************************************/
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <math.h>
  34. #include "mdct.h"
  35. #include "os.h"
  36. #include "misc.h"
  37. /* build lookups for trig functions; also pre-figure scaling and
  38. some window function algebra. */
  39. void mdct_init(mdct_lookup *lookup,int n){
  40. int *bitrev=_ogg_malloc(sizeof(int)*(n/4));
  41. float *trig=_ogg_malloc(sizeof(float)*(n+n/4));
  42. float *AE=trig;
  43. float *AO=trig+1;
  44. float *BE=AE+n/2;
  45. float *BO=BE+1;
  46. float *CE=BE+n/2;
  47. float *CO=CE+1;
  48. int i;
  49. int log2n=lookup->log2n=rint(log(n)/log(2));
  50. lookup->n=n;
  51. lookup->trig=trig;
  52. lookup->bitrev=bitrev;
  53. /* trig lookups... */
  54. for(i=0;i<n/4;i++){
  55. AE[i*2]=cos((M_PI/n)*(4*i));
  56. AO[i*2]=-sin((M_PI/n)*(4*i));
  57. BE[i*2]=cos((M_PI/(2*n))*(2*i+1));
  58. BO[i*2]=sin((M_PI/(2*n))*(2*i+1));
  59. }
  60. for(i=0;i<n/8;i++){
  61. CE[i*2]=cos((M_PI/n)*(4*i+2));
  62. CO[i*2]=-sin((M_PI/n)*(4*i+2));
  63. }
  64. /* bitreverse lookup... */
  65. {
  66. int mask=(1<<(log2n-1))-1,i,j;
  67. int msb=1<<(log2n-2);
  68. for(i=0;i<n/8;i++){
  69. int acc=0;
  70. for(j=0;msb>>j;j++)
  71. if((msb>>j)&i)acc|=1<<j;
  72. bitrev[i*2]=((~acc)&mask);
  73. bitrev[i*2+1]=acc;
  74. }
  75. }
  76. }
  77. void mdct_clear(mdct_lookup *l){
  78. if(l){
  79. if(l->trig)free(l->trig);
  80. if(l->bitrev)free(l->bitrev);
  81. memset(l,0,sizeof(mdct_lookup));
  82. }
  83. }
  84. static float *_mdct_kernel(float *x, float *w,
  85. int n, int n2, int n4, int n8,
  86. mdct_lookup *init){
  87. int i;
  88. /* step 2 */
  89. {
  90. float *xA=x+n4;
  91. float *xB=x;
  92. float *w2=w+n4;
  93. float *A=init->trig+n2;
  94. float x0,x1;
  95. i=0;
  96. do{
  97. x0=*xA - *xB;
  98. w2[i]= *xA++ + *xB++;
  99. x1= *xA - *xB;
  100. A-=4;
  101. w[i++]= x0 * A[0] + x1 * A[1];
  102. w[i]= x1 * A[0] - x0 * A[1];
  103. w2[i++]= *xA++ + *xB++;
  104. }while(i<n4);
  105. }
  106. /* step 3 */
  107. {
  108. int r,s;
  109. for(i=0;i<init->log2n-3;i++){
  110. int k0=n>>(i+2);
  111. int k1=1<<(i+3);
  112. int wbase=n2-2;
  113. float *A=init->trig;
  114. float *temp;
  115. for(r=0;r<(k0>>2);r++){
  116. int w1=wbase;
  117. int w2=w1-(k0>>1);
  118. float AEv= A[0],wA;
  119. float AOv= A[1],wB;
  120. int unroll=i;
  121. wbase-=2;
  122. k0++;
  123. unroll--;
  124. if(unroll>0){
  125. s=2<<unroll;
  126. s>>=1;
  127. do{
  128. wB =w[w1] -w[w2];
  129. x[w1] =w[w1] +w[w2];
  130. wA =w[++w1] -w[++w2];
  131. x[w1] =w[w1] +w[w2];
  132. x[w2] =wA*AEv - wB*AOv;
  133. x[w2-1]=wB*AEv + wA*AOv;
  134. w1-=k0;
  135. w2-=k0;
  136. wB =w[w1] -w[w2];
  137. x[w1] =w[w1] +w[w2];
  138. wA =w[++w1] -w[++w2];
  139. x[w1] =w[w1] +w[w2];
  140. x[w2] =wA*AEv - wB*AOv;
  141. x[w2-1]=wB*AEv + wA*AOv;
  142. w1-=k0;
  143. w2-=k0;
  144. wB =w[w1] -w[w2];
  145. x[w1] =w[w1] +w[w2];
  146. wA =w[++w1] -w[++w2];
  147. x[w1] =w[w1] +w[w2];
  148. x[w2] =wA*AEv - wB*AOv;
  149. x[w2-1]=wB*AEv + wA*AOv;
  150. w1-=k0;
  151. w2-=k0;
  152. wB =w[w1] -w[w2];
  153. x[w1] =w[w1] +w[w2];
  154. wA =w[++w1] -w[++w2];
  155. x[w1] =w[w1] +w[w2];
  156. x[w2] =wA*AEv - wB*AOv;
  157. x[w2-1]=wB*AEv + wA*AOv;
  158. w1-=k0;
  159. w2-=k0;
  160. }while(--s);
  161. }else{
  162. s=2<<i;
  163. do{
  164. wB =w[w1] -w[w2];
  165. x[w1] =w[w1] +w[w2];
  166. wA =w[++w1] -w[++w2];
  167. x[w1] =w[w1] +w[w2];
  168. x[w2] =wA*AEv - wB*AOv;
  169. x[w2-1]=wB*AEv + wA*AOv;
  170. w1-=k0;
  171. w2-=k0;
  172. }while(--s);
  173. }
  174. k0--;
  175. A+=k1;
  176. }
  177. temp=w;
  178. w=x;
  179. x=temp;
  180. }
  181. }
  182. /* step 4, 5, 6, 7 */
  183. {
  184. float *C=init->trig+n;
  185. int *bit=init->bitrev;
  186. float *x1=x;
  187. float *x2=x+n2-1;
  188. i=n8-1;
  189. do{
  190. int t1=*bit++;
  191. int t2=*bit++;
  192. float wA=w[t1]-w[t2+1];
  193. float wB=w[t1-1]+w[t2];
  194. float wC=w[t1]+w[t2+1];
  195. float wD=w[t1-1]-w[t2];
  196. float wACE=wA* *C;
  197. float wBCE=wB* *C++;
  198. float wACO=wA* *C;
  199. float wBCO=wB* *C++;
  200. *x1++=( wC+wACO+wBCE)*.5;
  201. *x2--=(-wD+wBCO-wACE)*.5;
  202. *x1++=( wD+wBCO-wACE)*.5;
  203. *x2--=( wC-wACO-wBCE)*.5;
  204. }while(i--);
  205. }
  206. return(x);
  207. }
  208. void mdct_forward(mdct_lookup *init, float *in, float *out){
  209. int n=init->n;
  210. float *x=alloca(sizeof(float)*(n/2));
  211. float *w=alloca(sizeof(float)*(n/2));
  212. float *xx;
  213. int n2=n>>1;
  214. int n4=n>>2;
  215. int n8=n>>3;
  216. int i;
  217. /* window + rotate + step 1 */
  218. {
  219. float tempA,tempB;
  220. int in1=n2+n4-4;
  221. int in2=in1+5;
  222. float *A=init->trig+n2;
  223. i=0;
  224. for(i=0;i<n8;i+=2){
  225. A-=2;
  226. tempA= in[in1+2] + in[in2];
  227. tempB= in[in1] + in[in2+2];
  228. in1 -=4;in2 +=4;
  229. x[i]= tempB*A[1] + tempA*A[0];
  230. x[i+1]= tempB*A[0] - tempA*A[1];
  231. }
  232. in2=1;
  233. for(;i<n2-n8;i+=2){
  234. A-=2;
  235. tempA= in[in1+2] - in[in2];
  236. tempB= in[in1] - in[in2+2];
  237. in1 -=4;in2 +=4;
  238. x[i]= tempB*A[1] + tempA*A[0];
  239. x[i+1]= tempB*A[0] - tempA*A[1];
  240. }
  241. in1=n-4;
  242. for(;i<n2;i+=2){
  243. A-=2;
  244. tempA= -in[in1+2] - in[in2];
  245. tempB= -in[in1] - in[in2+2];
  246. in1 -=4;in2 +=4;
  247. x[i]= tempB*A[1] + tempA*A[0];
  248. x[i+1]= tempB*A[0] - tempA*A[1];
  249. }
  250. }
  251. xx=_mdct_kernel(x,w,n,n2,n4,n8,init);
  252. /* step 8 */
  253. {
  254. float *B=init->trig+n2;
  255. float *out2=out+n2;
  256. float scale=4./n;
  257. for(i=0;i<n4;i++){
  258. out[i] =(xx[0]*B[0]+xx[1]*B[1])*scale;
  259. *(--out2)=(xx[0]*B[1]-xx[1]*B[0])*scale;
  260. xx+=2;
  261. B+=2;
  262. }
  263. }
  264. }
  265. void mdct_backward(mdct_lookup *init, float *in, float *out){
  266. int n=init->n;
  267. float *x=alloca(sizeof(float)*(n/2));
  268. float *w=alloca(sizeof(float)*(n/2));
  269. float *xx;
  270. int n2=n>>1;
  271. int n4=n>>2;
  272. int n8=n>>3;
  273. int i;
  274. /* rotate + step 1 */
  275. {
  276. float *inO=in+1;
  277. float *xO= x;
  278. float *A=init->trig+n2;
  279. for(i=0;i<n8;i++){
  280. A-=2;
  281. *xO++=-*(inO+2)*A[1] - *inO*A[0];
  282. *xO++= *inO*A[1] - *(inO+2)*A[0];
  283. inO+=4;
  284. }
  285. inO=in+n2-4;
  286. for(i=0;i<n8;i++){
  287. A-=2;
  288. *xO++=*inO*A[1] + *(inO+2)*A[0];
  289. *xO++=*inO*A[0] - *(inO+2)*A[1];
  290. inO-=4;
  291. }
  292. }
  293. xx=_mdct_kernel(x,w,n,n2,n4,n8,init);
  294. /* step 8 */
  295. {
  296. float *B=init->trig+n2;
  297. int o1=n4,o2=o1-1;
  298. int o3=n4+n2,o4=o3-1;
  299. for(i=0;i<n4;i++){
  300. float temp1= (*xx * B[1] - *(xx+1) * B[0]);
  301. float temp2=-(*xx * B[0] + *(xx+1) * B[1]);
  302. out[o1]=-temp1;
  303. out[o2]= temp1;
  304. out[o3]= temp2;
  305. out[o4]= temp2;
  306. o1++;
  307. o2--;
  308. o3++;
  309. o4--;
  310. xx+=2;
  311. B+=2;
  312. }
  313. }
  314. }