📄 ifft_radix4_2_cplx.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 + -