filtbank.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:18k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FAAC - Freeware Advanced Audio Coder
  3.  * Copyright (C) 2001 Menno Bakker
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  * You should have received a copy of the GNU Lesser General Public
  15.  * License along with this library; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  * $Id: filtbank.c,v 1.3 2001/06/04 23:02:24 wmay Exp $
  19.  */
  20. /*
  21.  * CHANGES:
  22.  *  2001/01/17: menno: Added frequency cut off filter.
  23.  *
  24.  */
  25. #include <math.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include "coder.h"
  29. #include "filtbank.h"
  30. #include "frame.h"
  31. #include "fft.h"
  32. #include "util.h"
  33. #define  TWOPI       2*M_PI
  34. void FilterBankInit(faacEncHandle hEncoder)
  35. {
  36. unsigned int i, channel;
  37. for (channel = 0; channel < hEncoder->numChannels; channel++) {
  38. hEncoder->freqBuff[channel] = (double*)AllocMemory(2*FRAME_LEN*sizeof(double));
  39. hEncoder->overlapBuff[channel] = (double*)AllocMemory(FRAME_LEN*sizeof(double));
  40. SetMemory(hEncoder->overlapBuff[channel], 0, FRAME_LEN*sizeof(double));
  41. }
  42. hEncoder->sin_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
  43. hEncoder->sin_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
  44. hEncoder->kbd_window_long = (double*)AllocMemory(BLOCK_LEN_LONG*sizeof(double));
  45. hEncoder->kbd_window_short = (double*)AllocMemory(BLOCK_LEN_SHORT*sizeof(double));
  46. for( i=0; i<BLOCK_LEN_LONG; i++ )
  47. hEncoder->sin_window_long[i] = sin((M_PI/(2*BLOCK_LEN_LONG)) * (i + 0.5));
  48. for( i=0; i<BLOCK_LEN_SHORT; i++ )
  49. hEncoder->sin_window_short[i] = sin((M_PI/(2*BLOCK_LEN_SHORT)) * (i + 0.5));
  50. CalculateKBDWindow(hEncoder->kbd_window_long, 4, BLOCK_LEN_LONG*2);
  51. CalculateKBDWindow(hEncoder->kbd_window_short, 6, BLOCK_LEN_SHORT*2);
  52. }
  53. void FilterBankEnd(faacEncHandle hEncoder)
  54. {
  55. unsigned int channel;
  56. for (channel = 0; channel < hEncoder->numChannels; channel++) {
  57. if (hEncoder->freqBuff[channel]) FreeMemory(hEncoder->freqBuff[channel]);
  58. if (hEncoder->overlapBuff[channel]) FreeMemory(hEncoder->overlapBuff[channel]);
  59. }
  60. if (hEncoder->sin_window_long) FreeMemory(hEncoder->sin_window_long);
  61. if (hEncoder->sin_window_short) FreeMemory(hEncoder->sin_window_short);
  62. if (hEncoder->kbd_window_long) FreeMemory(hEncoder->kbd_window_long);
  63. if (hEncoder->kbd_window_short) FreeMemory(hEncoder->kbd_window_short);
  64. }
  65. void FilterBank(faacEncHandle hEncoder,
  66. CoderInfo *coderInfo,
  67. double *p_in_data,
  68. double *p_out_mdct,
  69. double *p_overlap,
  70. int overlap_select)
  71. {
  72. double *p_o_buf, *first_window, *second_window;
  73. double *transf_buf;
  74. int k, i;
  75. int block_type = coderInfo->block_type;
  76. transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
  77. /* create / shift old values */
  78. /* We use p_overlap here as buffer holding the last frame time signal*/
  79. if(overlap_select != MNON_OVERLAPPED) {
  80. memcpy(transf_buf, p_overlap, FRAME_LEN*sizeof(double));
  81. memcpy(transf_buf+BLOCK_LEN_LONG, p_in_data, FRAME_LEN*sizeof(double));
  82. memcpy(p_overlap, p_in_data, FRAME_LEN*sizeof(double));
  83. } else {
  84. memcpy(transf_buf, p_in_data, 2*FRAME_LEN*sizeof(double));
  85. }
  86. /*  Window shape processing */
  87. if(overlap_select != MNON_OVERLAPPED) {
  88. switch (coderInfo->prev_window_shape) {
  89. case SINE_WINDOW:
  90. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
  91. first_window = hEncoder->sin_window_long;
  92. else
  93. first_window = hEncoder->sin_window_short;
  94. break;
  95. case KBD_WINDOW:
  96. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
  97. first_window = hEncoder->kbd_window_long;
  98. else
  99. first_window = hEncoder->kbd_window_short;
  100. break;
  101. }
  102. switch (coderInfo->window_shape){
  103. case SINE_WINDOW:
  104. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
  105. second_window = hEncoder->sin_window_long;
  106. else
  107. second_window = hEncoder->sin_window_short;
  108. break;
  109. case KBD_WINDOW:
  110. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
  111. second_window = hEncoder->kbd_window_long;
  112. else
  113. second_window = hEncoder->kbd_window_short;
  114. break;
  115. }
  116. } else {
  117. /* Always long block and sine window for LTP */
  118. first_window = hEncoder->sin_window_long;
  119. second_window = hEncoder->sin_window_long;
  120. }
  121. /* Set ptr to transf-Buffer */
  122. p_o_buf = transf_buf;
  123. /* Separate action for each Block Type */
  124. switch (block_type) {
  125.     case ONLY_LONG_WINDOW :
  126. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++){
  127. p_out_mdct[i] = p_o_buf[i] * first_window[i];
  128. p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
  129. }
  130. MDCT( p_out_mdct, 2*BLOCK_LEN_LONG );
  131. break;
  132.     case LONG_SHORT_WINDOW :
  133. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  134. p_out_mdct[i] = p_o_buf[i] * first_window[i];
  135. memcpy(p_out_mdct+BLOCK_LEN_LONG,p_o_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
  136. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
  137. p_out_mdct[i+BLOCK_LEN_LONG+NFLAT_LS] = p_o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
  138. SetMemory(p_out_mdct+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
  139. MDCT( p_out_mdct, 2*BLOCK_LEN_LONG );
  140. break;
  141.     case SHORT_LONG_WINDOW :
  142. SetMemory(p_out_mdct,0,NFLAT_LS*sizeof(double));
  143. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
  144. p_out_mdct[i+NFLAT_LS] = p_o_buf[i+NFLAT_LS] * first_window[i];
  145. memcpy(p_out_mdct+NFLAT_LS+BLOCK_LEN_SHORT,p_o_buf+NFLAT_LS+BLOCK_LEN_SHORT,NFLAT_LS*sizeof(double));
  146. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  147. p_out_mdct[i+BLOCK_LEN_LONG] = p_o_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
  148. MDCT( p_out_mdct, 2*BLOCK_LEN_LONG );
  149. break;
  150.     case ONLY_SHORT_WINDOW :
  151. p_o_buf += NFLAT_LS;
  152. for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
  153. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++ ){
  154. p_out_mdct[i] = p_o_buf[i] * first_window[i];
  155. p_out_mdct[i+BLOCK_LEN_SHORT] = p_o_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
  156. }
  157. MDCT( p_out_mdct, 2*BLOCK_LEN_SHORT );
  158. p_out_mdct += BLOCK_LEN_SHORT;
  159. p_o_buf += BLOCK_LEN_SHORT;
  160. first_window = second_window;
  161. }
  162. break;
  163. }
  164. if (transf_buf) FreeMemory(transf_buf);
  165. }
  166. void IFilterBank(faacEncHandle hEncoder,
  167.  CoderInfo *coderInfo,
  168.  double *p_in_data,
  169.  double *p_out_data,
  170.  double *p_overlap,
  171.  int overlap_select)
  172. {
  173. double *o_buf, *transf_buf, *overlap_buf;
  174. double *first_window, *second_window;
  175. double  *fp;
  176. int k, i;
  177. int block_type = coderInfo->block_type;
  178. transf_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
  179. overlap_buf = (double*)AllocMemory(2*BLOCK_LEN_LONG*sizeof(double));
  180. /*  Window shape processing */
  181. if (overlap_select != MNON_OVERLAPPED) {
  182. // switch (coderInfo->prev_window_shape){
  183. // case SINE_WINDOW:
  184. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
  185. first_window = hEncoder->sin_window_long;
  186. else
  187. first_window = hEncoder->sin_window_short;
  188. // break;
  189. // case KBD_WINDOW:
  190. // if ( (block_type == ONLY_LONG_WINDOW) || (block_type == LONG_SHORT_WINDOW))
  191. // first_window = hEncoder->kbd_window_long;
  192. // else
  193. // first_window = hEncoder->kbd_window_short;
  194. // break;
  195. // }
  196. // switch (coderInfo->window_shape){
  197. // case SINE_WINDOW:
  198. if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
  199. second_window = hEncoder->sin_window_long;
  200. else
  201. second_window = hEncoder->sin_window_short;
  202. // break;
  203. // case KBD_WINDOW:
  204. // if ( (block_type == ONLY_LONG_WINDOW) || (block_type == SHORT_LONG_WINDOW))
  205. // second_window = hEncoder->kbd_window_long;
  206. // else
  207. // second_window = hEncoder->kbd_window_short;
  208. // break;
  209. // }
  210. } else {
  211. /* Always long block and sine window for LTP */
  212. first_window  = hEncoder->sin_window_long;
  213. second_window = hEncoder->sin_window_long;
  214. }
  215. /* Assemble overlap buffer */
  216. memcpy(overlap_buf,p_overlap,BLOCK_LEN_LONG*sizeof(double));
  217. o_buf = overlap_buf;
  218. /* Separate action for each Block Type */
  219. switch( block_type ) {
  220.     case ONLY_LONG_WINDOW :
  221. memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
  222. IMDCT( transf_buf, 2*BLOCK_LEN_LONG );
  223. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  224. transf_buf[i] *= first_window[i];
  225. if (overlap_select != MNON_OVERLAPPED) {
  226. for ( i = 0 ; i < BLOCK_LEN_LONG; i++ ){
  227. o_buf[i] += transf_buf[i];
  228. o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
  229. }
  230. } else { /* overlap_select == NON_OVERLAPPED */
  231. for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
  232. transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
  233.         }
  234. break;
  235.     case LONG_SHORT_WINDOW :
  236. memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
  237. IMDCT( transf_buf, 2*BLOCK_LEN_LONG );
  238. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  239. transf_buf[i] *= first_window[i];
  240.         if (overlap_select != MNON_OVERLAPPED) {
  241. for ( i = 0 ; i < BLOCK_LEN_LONG; i++ )
  242. o_buf[i] += transf_buf[i];
  243. memcpy(o_buf+BLOCK_LEN_LONG,transf_buf+BLOCK_LEN_LONG,NFLAT_LS*sizeof(double));
  244. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
  245. o_buf[i+BLOCK_LEN_LONG+NFLAT_LS] = transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] * second_window[BLOCK_LEN_SHORT-i-1];
  246. SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
  247.         } else { /* overlap_select == NON_OVERLAPPED */
  248. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
  249. transf_buf[i+BLOCK_LEN_LONG+NFLAT_LS] *= second_window[BLOCK_LEN_SHORT-i-1];
  250. SetMemory(transf_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
  251. }
  252. break;
  253. case SHORT_LONG_WINDOW :
  254. memcpy(transf_buf, p_in_data,BLOCK_LEN_LONG*sizeof(double));
  255. IMDCT( transf_buf, 2*BLOCK_LEN_LONG );
  256. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++)
  257. transf_buf[i+NFLAT_LS] *= first_window[i];
  258. if (overlap_select != MNON_OVERLAPPED) {
  259. for ( i = 0 ; i < BLOCK_LEN_SHORT; i++ )
  260. o_buf[i+NFLAT_LS] += transf_buf[i+NFLAT_LS];
  261. memcpy(o_buf+BLOCK_LEN_SHORT+NFLAT_LS,transf_buf+BLOCK_LEN_SHORT+NFLAT_LS,NFLAT_LS*sizeof(double));
  262. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  263. o_buf[i+BLOCK_LEN_LONG] = transf_buf[i+BLOCK_LEN_LONG] * second_window[BLOCK_LEN_LONG-i-1];
  264. } else { /* overlap_select == NON_OVERLAPPED */
  265. SetMemory(transf_buf,0,NFLAT_LS*sizeof(double));
  266. for ( i = 0 ; i < BLOCK_LEN_LONG ; i++)
  267. transf_buf[i+BLOCK_LEN_LONG] *= second_window[BLOCK_LEN_LONG-i-1];
  268. }
  269. break;
  270. case ONLY_SHORT_WINDOW :
  271. if (overlap_select != MNON_OVERLAPPED) {
  272. fp = o_buf + NFLAT_LS;
  273. } else { /* overlap_select == NON_OVERLAPPED */
  274. fp = transf_buf;
  275. }
  276. for ( k=0; k < MAX_SHORT_WINDOWS; k++ ) {
  277. memcpy(transf_buf,p_in_data,BLOCK_LEN_SHORT*sizeof(double));
  278. IMDCT( transf_buf, 2*BLOCK_LEN_SHORT );
  279. p_in_data += BLOCK_LEN_SHORT;
  280. if (overlap_select != MNON_OVERLAPPED) {
  281. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
  282. transf_buf[i] *= first_window[i];
  283. fp[i] += transf_buf[i];
  284. fp[i+BLOCK_LEN_SHORT] = transf_buf[i+BLOCK_LEN_SHORT] * second_window[BLOCK_LEN_SHORT-i-1];
  285. }
  286. fp += BLOCK_LEN_SHORT;
  287. } else { /* overlap_select == NON_OVERLAPPED */
  288. for ( i = 0 ; i < BLOCK_LEN_SHORT ; i++){
  289. fp[i] *= first_window[i];
  290. fp[i+BLOCK_LEN_SHORT] *= second_window[BLOCK_LEN_SHORT-i-1];
  291. }
  292. fp += 2*BLOCK_LEN_SHORT;
  293. }
  294. first_window = second_window;
  295. }
  296. SetMemory(o_buf+BLOCK_LEN_LONG+NFLAT_LS+BLOCK_LEN_SHORT,0,NFLAT_LS*sizeof(double));
  297. break;
  298. }
  299. if (overlap_select != MNON_OVERLAPPED)
  300. memcpy(p_out_data,o_buf,BLOCK_LEN_LONG*sizeof(double));
  301. else  /* overlap_select == NON_OVERLAPPED */
  302. memcpy(p_out_data,transf_buf,2*BLOCK_LEN_LONG*sizeof(double));
  303. /* save unused output data */
  304. memcpy(p_overlap,o_buf+BLOCK_LEN_LONG,BLOCK_LEN_LONG*sizeof(double));
  305. if (overlap_buf) FreeMemory(overlap_buf);
  306. if (transf_buf) FreeMemory(transf_buf);
  307. }
  308. void specFilter(double *freqBuff,
  309. int sampleRate,
  310. int lowpassFreq,
  311. int specLen
  312. )
  313. {
  314. int lowpass,xlowpass;
  315. /* calculate the last line which is not zero */
  316. lowpass = (lowpassFreq * specLen) / (sampleRate>>1) + 1;
  317. xlowpass = (lowpass < specLen) ? lowpass : specLen ;
  318. SetMemory(freqBuff+xlowpass,0,(specLen-xlowpass)*sizeof(double));
  319. }
  320. static double Izero(double x)
  321. {
  322. const double IzeroEPSILON = 1E-41;  /* Max error acceptable in Izero */
  323. double sum, u, halfx, temp;
  324. int n;
  325. sum = u = n = 1;
  326. halfx = x/2.0;
  327. do {
  328. temp = halfx/(double)n;
  329. n += 1;
  330. temp *= temp;
  331. u *= temp;
  332. sum += u;
  333. } while (u >= IzeroEPSILON*sum);
  334. return(sum);
  335. }
  336. static void CalculateKBDWindow(double* win, double alpha, int length)
  337. {
  338. int i;
  339. double IBeta;
  340. double tmp;
  341. double sum = 0.0;
  342. alpha *= M_PI;
  343. IBeta = 1.0/Izero(alpha);
  344. /* calculate lower half of Kaiser Bessel window */
  345. for(i=0; i<(length>>1); i++) {
  346. tmp = 4.0*(double)i/(double)length - 1.0;
  347. win[i] = Izero(alpha*sqrt(1.0-tmp*tmp))*IBeta;
  348. sum += win[i];
  349. }
  350. sum = 1.0/sum;
  351. tmp = 0.0;
  352. /* calculate lower half of window */
  353. for(i=0; i<(length>>1); i++) {
  354. tmp += win[i];
  355. win[i] = sqrt(tmp*sum);
  356. }
  357. }
  358. static void MDCT(double *data, int N)
  359. {
  360. double *xi, *xr;
  361. double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
  362. double freq = TWOPI / N;
  363. double cosfreq8, sinfreq8;
  364. int i, n;
  365. xi = (double*)AllocMemory((N >> 2)*sizeof(double));
  366. xr = (double*)AllocMemory((N >> 2)*sizeof(double));
  367. /* prepare for recurrence relation in pre-twiddle */
  368. cfreq = cos (freq);
  369. sfreq = sin (freq);
  370. cosfreq8 = cos (freq * 0.125);
  371. sinfreq8 = sin (freq * 0.125);
  372. c = cosfreq8;
  373. s = sinfreq8;
  374. for (i = 0; i < (N >> 2); i++) {
  375. /* calculate real and imaginary parts of g(n) or G(p) */
  376. n = (N >> 1) - 1 - 2 * i;
  377. if (i < (N >> 3))
  378. tempr = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n = N / 2 - 1 - 2i */
  379. else
  380. tempr = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n = N / 2 - 1 - 2i */
  381. n = 2 * i;
  382. if (i < (N >> 3))
  383. tempi = data [(N >> 2) + n] - data [(N >> 2) - 1 - n]; /* use first form of e(n) for n=2i */
  384. else
  385. tempi = data [(N >> 2) + n] + data [N + (N >> 2) - 1 - n]; /* use second form of e(n) for n=2i*/
  386. /* calculate pre-twiddled FFT input */
  387. xr[i] = tempr * c + tempi * s;
  388. xi[i] = tempi * c - tempr * s;
  389. /* use recurrence to prepare cosine and sine for next value of i */
  390. cold = c;
  391. c = c * cfreq - s * sfreq;
  392. s = s * cfreq + cold * sfreq;
  393. }
  394. /* Perform in-place complex FFT of length N/4 */
  395. switch (N) {
  396.     case 256:
  397. srfft(xr, xi, 6);
  398. break;
  399.     case 2048:
  400. srfft(xr, xi, 9);
  401. }
  402. /* prepare for recurrence relations in post-twiddle */
  403. c = cosfreq8;
  404. s = sinfreq8;
  405. /* post-twiddle FFT output and then get output data */
  406. for (i = 0; i < (N >> 2); i++) {
  407. /* get post-twiddled FFT output  */
  408. tempr = 2. * (xr[i] * c + xi[i] * s);
  409. tempi = 2. * (xi[i] * c - xr[i] * s);
  410. /* fill in output values */
  411. data [2 * i] = -tempr;   /* first half even */
  412. data [(N >> 1) - 1 - 2 * i] = tempi;  /* first half odd */
  413. data [(N >> 1) + 2 * i] = -tempi;  /* second half even */
  414. data [N - 1 - 2 * i] = tempr;  /* second half odd */
  415. /* use recurrence to prepare cosine and sine for next value of i */
  416. cold = c;
  417. c = c * cfreq - s * sfreq;
  418. s = s * cfreq + cold * sfreq;
  419. }
  420. if (xr) FreeMemory(xr);
  421. if (xi) FreeMemory(xi);
  422. }
  423. static void IMDCT(double *data, int N)
  424. {
  425. double *xi, *xr;
  426. double tempr, tempi, c, s, cold, cfreq, sfreq; /* temps for pre and post twiddle */
  427. double freq = 2.0 * M_PI / N;
  428. double fac, cosfreq8, sinfreq8;
  429. int i;
  430. xi = (double*)AllocMemory((N >> 2)*sizeof(double));
  431. xr = (double*)AllocMemory((N >> 2)*sizeof(double));
  432. /* Choosing to allocate 2/N factor to Inverse Xform! */
  433. fac = 2. / N; /* remaining 2/N from 4/N IFFT factor */
  434. /* prepare for recurrence relation in pre-twiddle */
  435. cfreq = cos (freq);
  436. sfreq = sin (freq);
  437. cosfreq8 = cos (freq * 0.125);
  438. sinfreq8 = sin (freq * 0.125);
  439. c = cosfreq8;
  440. s = sinfreq8;
  441. for (i = 0; i < (N >> 2); i++) {
  442. /* calculate real and imaginary parts of g(n) or G(p) */
  443. tempr = -data[2 * i];
  444. tempi = data[(N >> 1) - 1 - 2 * i];
  445. /* calculate pre-twiddled FFT input */
  446. xr[i] = tempr * c - tempi * s;
  447. xi[i] = tempi * c + tempr * s;
  448. /* use recurrence to prepare cosine and sine for next value of i */
  449. cold = c;
  450. c = c * cfreq - s * sfreq;
  451. s = s * cfreq + cold * sfreq;
  452. }
  453.     /* Perform in-place complex IFFT of length N/4 */
  454. switch (N) {
  455.     case 256:
  456. srifft(xr, xi, 6);
  457. break;
  458.     case 2048:
  459. srifft(xr, xi, 9);
  460. }
  461.     /* prepare for recurrence relations in post-twiddle */
  462.     c = cosfreq8;
  463.     s = sinfreq8;
  464.     /* post-twiddle FFT output and then get output data */
  465.     for (i = 0; i < (N >> 2); i++) {
  466. /* get post-twiddled FFT output  */
  467. tempr = fac * (xr[i] * c - xi[i] * s);
  468. tempi = fac * (xi[i] * c + xr[i] * s);
  469. /* fill in output values */
  470. data [(N >> 1) + (N >> 2) - 1 - 2 * i] = tempr;
  471. if (i < (N >> 3))
  472. data [(N >> 1) + (N >> 2) + 2 * i] = tempr;
  473. else
  474. data [2 * i - (N >> 2)] = -tempr;
  475. data [(N >> 2) + 2 * i] = tempi;
  476. if (i < (N >> 3))
  477. data [(N >> 2) - 1 - 2 * i] = -tempi;
  478. else
  479. data [(N >> 2) + N - 1 - 2*i] = tempi;
  480. /* use recurrence to prepare cosine and sine for next value of i */
  481. cold = c;
  482. c = c * cfreq - s * sfreq;
  483. s = s * cfreq + cold * sfreq;
  484. }
  485. if (xr) FreeMemory(xr);
  486. if (xi) FreeMemory(xi);
  487. }