⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ifft_radix4_2_cplx.c

📁 同样是浮点型的fft算法一样为vc开发的
💻 C
字号:
/*
 *	DATE:05/31/2006
 *
 *	AUTHOR:CHEN PENG
 *
 *	VERSION:ORIGINAL	05/31/2006
 *			MODIFIED	06/02/2006
 *						06/27/2006
 */
 
/******************************************************************************\
*	FUNCTION:	void ifft_radix4_2_cplx( int x[],
*						 				 int num_r2,
*						 				 int w[],
*						 				 short powerOf4,
*										)
*
*	AGRUMENTS:	x[num_r2]	Input and output sequences. Size num_r2 complex
*							elements
*
*				num_r2		Number of complex elements in vector x. Must be
*							power of 2 such that 4 <= num_r2 <= 65536
*				w[num_r2]	Vector of FFT coefficients of size num_r2 elements
*			
*				power0f4	Flag which indicates if size of sequence is power of 4
*				
*	DESCRIPTION:	This routine is used to compute IFFT of a complex sequence 
*					size num_r2, a power of 2 or 4, with "decimation-in-frequency
*					radix4 combined with radix2 decomposition" method . The 
*					output is in normal order. Each complex value is with
*					interleaved 16-bit real and imaginary parts.
*
*	REQUIREMENTS:	1. 4 <= num_r2 <= 65536( num_r2 a power of 2)
*					2. x data is stored in the order real[0],image[0],real[1],...
*					3. x is aligned on a 4*num_r2 byte boundary 
*					4. The code is LITTLE ENDIAN
*
\******************************************************************************/

void ifft_radix4_2_cplx( int x[],
						 int num_r2,
						 int w[],
						 short powerOf4
						){
	int n1, n2, ie, num_r4;			//Loop variables 
	int iw1, iw2, iw3;					//FFT coefficients index
	int ix0, ix1, ix2, ix3;				//Data sequences index
	int ix0b, ix1b, ix2b, ix3b;			//Data sequences index only for radix4 mixed with radix2
	int iStage, iButterfly;				//Stage and butterfly flag
	int xtmph0, xtmph1, xtmph2, xtmph3;
	int xtmpl0, xtmpl1, xtmpl2, xtmpl3;//Temporary high and low 16-bit results				
	int temp0, temp1, temp2;			//Temporary variables
	int temphl1, temphl2, temphl3;		 
	num_r4 = num_r2;
	n2 = 1;
	ie = (num_r2 >> 2);
	/*
	 *If input sequences has size of power of 4, IFFT will be computed with method radix4,
	 *othewise, firstly the frequency components is decomposited with method radix2 into two 
	 *separate sequences each with size of num_r4, then IFFT calculation for each part
	 *performs under radix4 respectively.
	 */
	if(!powerOf4){				
		/*===================*\
		 *IFFT radix4 firstly
		\*===================*/
		/* 
		 * x(x) 	   = A(n) + Wn(-n)B(n)  + Wn(-2n)C(n) + Wn(-3n)D(n)
		 * x(x + N/4)  = A(n) + jWn(-n)B(n) - Wn(-2n)C(n) - jWn(-3n)D(n)
		 * x(x + N/2)  = A(n) - Wn(-n)B(n)  + Wn(-2n)C(n) - Wn(-3n)D(n)
		 * x(x + 3N/4) = A(n) - jWn(-n)B(n) - Wn(-2n)C(n) + jWn(-3n)D(n)
		 */ 
		num_r4 = num_r2 >> 1;	//size of each part for radix4 method
		for( iStage = num_r4; iStage > 1; iStage >>= 2 ){ 
			n1 = n2;
			n2 <<= 2;
			iw1 = 0;
			for( iButterfly = 0; iButterfly < n1; iButterfly++ ){
				iw2 = iw1 + iw1;
				iw3 = iw2 + iw1;
				for( ix0 = iButterfly; ix0 < num_r4; ix0 += n2 ){
					ix1 = ix0 + n1;
					ix2 = ix1 + n1;
					ix3 = ix2 + n1; 
                    xtmph0 = (x[ix0] >> 2) & 0xffff0000;
					xtmpl0 = ((x[ix0] & 0x0000ffff) << 16) >> 18 & 0x0000ffff;
					x[ix0] = xtmph0 | xtmpl0 ;        //division by 4
					/********************************************\
					 *IFFT calculation for former num_r4 points
					\********************************************/
					//real and imaginary parts of C(n)
					xtmph1 = ((_smpyh(x[ix1],w[iw2]) - _smpy(x[ix1],-w[iw2])) >> 2) & 0xffff0000;
					xtmpl1 = ((_smpylh(x[ix1],w[iw2]) + _smpyhl(x[ix1],-w[iw2])) >> 18) 
							& 0x0000ffff;
					temphl1 = xtmph1 | xtmpl1;
					//real and imaginary parts of B(n)
					xtmph2 = ((_smpyh(x[ix2],w[iw1]) - _smpy(x[ix2],-w[iw1])) >> 2) & 0xffff0000;
					xtmpl2 = ((_smpylh(x[ix2],w[iw1]) + _smpyhl(x[ix2],-w[iw1])) >> 18) 
							& 0x0000ffff;
					temphl2 = xtmph2 | xtmpl2;
					//real and imaginary parts of D(n)
					xtmph3 = ((_smpyh(x[ix3],w[iw3]) - _smpy(x[ix3],-w[iw3])) >> 2) & 0xffff0000;
					xtmpl3 = ((_smpylh(x[ix3],w[iw3]) + _smpyhl(x[ix3],-w[iw3])) >> 18) 
							& 0x0000ffff;
					temphl3 = xtmph3 | xtmpl3;
					temp0 = _add2(x[ix0], temphl1);
					temp1 = _add2(temphl2, temphl3); 
					temp2 = _add2(temp0, temp1);	//x(n)
					x[ix2] = _sub2(temp0,temp1);	//x(n + N/2)
					temp0 = _sub2(x[ix0], temphl1); 
					x[ix0] = temp2;					
					temp1 = _sub2(temphl2, temphl3);
					temp2 = ((-temp1) << 16) & 0xffff0000;
					temp1 = temp2 | ((temp1 >> 16) & 0x0000ffff);
					x[ix1] = _add2(temp0,temp1);	//x(n + N/4)
					x[ix3] = _sub2(temp0,temp1);	//x(n + 3N/4)
					
					/********************************************\
					 *IFFT calculation for latter num_r4 points
					\********************************************/ 
					ix0b = ix0 + num_r4; 
					ix1b = ix1 + num_r4;
					ix2b = ix2 + num_r4;
					ix3b = ix3 + num_r4;
					xtmph0 = (x[ix0b] >> 2) & 0xffff0000;
					xtmpl0 = ((x[ix0b] & 0x0000ffff) << 16) >> 18 & 0x0000ffff; 
					x[ix0b] = xtmph0 | xtmpl0 ;           //division by 4
					//real and imaginary parts of C(n)
					xtmph1 = ((_smpyh(x[ix1b],w[iw2]) - _smpy(x[ix1b],-w[iw2])) >> 2) & 0xffff0000;
					xtmpl1 = ((_smpylh(x[ix1b],w[iw2]) + _smpyhl(x[ix1b],-w[iw2])) >> 18) 
							& 0x0000ffff;
					temphl1 = xtmph1 | xtmpl1;
					//real and imaginary parts of B(n)
					xtmph2 = ((_smpyh(x[ix2b],w[iw1]) - _smpy(x[ix2b],-w[iw1])) >> 2) & 0xffff0000;
					xtmpl2 = ((_smpylh(x[ix2b],w[iw1]) + _smpyhl(x[ix2b],-w[iw1])) >> 18) 
							& 0x0000ffff;
					temphl2 = xtmph2 | xtmpl2;
					//real and imaginary parts of D(n)
					xtmph3 = ((_smpyh(x[ix3b],w[iw3]) - _smpy(x[ix3b],-w[iw3])) >> 2) & 0xffff0000;
					xtmpl3 = ((_smpylh(x[ix3b],w[iw3]) + _smpyhl(x[ix3b],-w[iw3])) >> 18) 
							& 0x0000ffff;
					temphl3 = xtmph3 | xtmpl3;
					temp0 = _add2(x[ix0b], temphl1);
					temp1 = _add2(temphl2, temphl3);
					temp2 = _add2(temp0, temp1);	//x(n)
					x[ix2b] = _sub2(temp0,temp1);	//x(n + N/2)
					temp0 = _sub2(x[ix0b], temphl1); 
				    x[ix0b] = temp2;					
					temp1 = _sub2(temphl2, temphl3);
					temp2 = ((-temp1) << 16) & 0xffff0000;
					temp1 = temp2 | ((temp1 >> 16) & 0x0000ffff);
					x[ix1b] = _add2(temp0,temp1);	//x(n + N/4)
					x[ix3b] = _sub2(temp0,temp1);	//x(n + 3N/4)	
				}
				iw1 += ie;             //Scaler equals to '1' due to radix4 
			}						   //computation is performed first.              
			ie >>= 2;
		} 
		/*========================*\
		 *IFFT radix2 afterwards
		\*========================*/
		n1 = n2;		
		n2 <<= 1;
		iw1 = 0;
		for(iButterfly = 0; iButterfly < n1; iButterfly++){
			for( ix0 = iButterfly; ix0 < num_r2; ix0 += n2 ){
				ix1 = ix0 + n1; 
				xtmph0 = (x[ix0] >> 1) & 0xffff0000;
				xtmpl0 = ((x[ix0] & 0x0000ffff) << 16) >> 17 & 0x0000ffff;
				x[ix0] = xtmph0 | xtmpl0 ; 		         	//division by 2
				xtmph1= ((_smpyh(x[ix1],w[iw1]) - _smpy(x[ix1],-w[iw1])) >> 1) & 0xffff0000;
				xtmpl1 = ((_smpylh(x[ix1],w[iw1]) + _smpyhl(x[ix1],-w[iw1])) >> 17) 
							& 0x0000ffff;
				temphl1 = xtmph1 | xtmpl1;
				x[ix1] = _sub2(x[ix0], temphl1);    //old points
				x[ix0] = _add2(x[ix0], temphl1);    //even points
			} 
			iw1 += 1;
		} 
	}
	else {
		/*=========================*\
		 *direct radix4 calculation
		\*=========================*/
		for( iStage = num_r4; iStage > 1; iStage >>= 2 ){
			n1 = n2;
			n2 <<= 2;
			iw1 = 0;
			for( iButterfly = 0; iButterfly < n1; iButterfly++ ){
				iw2 = iw1 + iw1;
				iw3 = iw2 + iw1;
				for( ix0 = iButterfly; ix0 < num_r4; ix0 += n2 ){
					ix1 = ix0 + n1;
					ix2 = ix1 + n1;
					ix3 = ix2 + n1; 
					//real and imaginary parts of A(n)  
					xtmph0 = (x[ix0] >> 2) & 0xffff0000;
					xtmpl0 = ((x[ix0] & 0x0000ffff) << 16) >> 18 & 0x0000ffff;
					x[ix0] = xtmph0 | xtmpl0; 
					//real and imaginary parts of C(n)
					xtmph1 = ((_smpyh(x[ix1],w[iw2]) - _smpy(x[ix1],-w[iw2])) >> 2) & 0xffff0000;
					xtmpl1 = (((_smpylh(x[ix1],w[iw2]) + _smpyhl(x[ix1],-w[iw2])) >> 18) 
							& 0x0000ffff);
					temphl1 = xtmph1 | xtmpl1;
					//real and imaginary parts of B(n)
					xtmph2 = ((_smpyh(x[ix2],w[iw1]) - _smpy(x[ix2],-w[iw1])) >> 2) & 0xffff0000;
					xtmpl2 = (((_smpylh(x[ix2],w[iw1]) + _smpyhl(x[ix2],-w[iw1])) >> 18) 
							& 0x0000ffff); 
					temphl2 = xtmph2 | xtmpl2;
					//real and imaginary parts of D(n)
					xtmph3 = ((_smpyh(x[ix3],w[iw3]) - _smpy(x[ix3],-w[iw3])) >> 2) & 0xffff0000;
					xtmpl3 = (((_smpylh(x[ix3],w[iw3]) + _smpyhl(x[ix3],-w[iw3])) >> 18) 
							& 0x0000ffff);
					temphl3 = xtmph3 | xtmpl3;
					temp0 = _add2(x[ix0], temphl1);
					temp1 = _add2(temphl2, temphl3);
					temp2 = _add2(temp0, temp1);	//x(n)
					x[ix2] = _sub2(temp0, temp1);	//x(n + N/2)
					temp0 = _sub2(x[ix0], temphl1); 
					x[ix0] = temp2;    
					temp1 = _sub2(temphl2, temphl3);
					temp2 = ((-temp1) << 16) & 0xffff0000;
					temp1 = temp2 | ((temp1 >> 16) & 0x0000ffff);
					x[ix1] = _add2(temp0,temp1) ;	//x(n + N/4)
					x[ix3] = _sub2(temp0,temp1) ;	//x(n + 3N/4)
				}
				iw1 += ie;	
			}
			ie >>= 2;			
		}
	}
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -