What steps are necessary to get the same impulse as before a FFT + IFFT.
At the moment I am trying out my code a bit and would like to do an FFT from an impulse response followed by an IFFT to generate the impulse response again. Actually I would like to change the frequency range a bit and look at the impulse response from that. However, I am already failing to get the same IR without changing the frequency range.
The impulse I generate looks like the original impulse, but the same impulse appears mirrored at the end.
What I tried before applying the IFFT:
- i set the result of the FFT from the half (to the Nyquist frequency) to 0.
- I mirrored the first half of the FFT result to the second half.
But the impulse response always has a mirrored impulse response at the end.
Perhaps the question is too trivial for many, however, I have not yet found the appropriate answer, perhaps not understood. Glad about any help.
Here also my Code:
void FFT::executeFFT(std::vector<double>* _data,std::vector<double>* _Intervall,std::string _Name)
{
if(_data !=nullptr|| real.empty() != true || imag.empty() != true){
for (int i = 0; i < real.size(); i++)
{
real[i] = 0.0; imag[i] = 0.0;
}
int le, ip, m, i, nm1, j, t, le1, inv = 0;
double ur, ui, tr, ti, tmpr, tmpi, nv2, k;
if (_hin) inv = 1;
else inv = -1;
for (int i = 0; i <= Nmax - 2; i++)
{
real[i] = _data->at(i+1);
}
m = round((log(Nmax) / log(2)));
nv2 = Nmax / 2;
nm1 = Nmax - 1;
j = 1;
//Vertauschung der Eingangsfolge
for (i = 1; i <= nm1; i++)
{
if (i < j) {
tmpr = real[j - 1];
tmpi = imag[j - 1];
real[j - 1] = real[i - 1];
imag[j - 1] = imag[i - 1];
real[i - 1] = tmpr;
imag[i - 1] = tmpi;
}
k = nv2;
while (k < j)
{
j = round(j - k);
k = k / 2.0;
}
j = round(j + k);
}
//Berrechnung der Butterflys
for (int l = 1; l <= m; l = l + 1)
{
le = 1;
for (t = 1; t <= l; t = t + 1)
{
le = le * 2;
}
le1 = round(le / 2);
ur = 1;
ui = 0;
for (j = 1; j <= le1; j++)
{
i = j;
while (i <= Nmax)
{
ip = i + le1;
tr = real[ip - 1] * ur - imag[ip - 1] * ui; //{ Berechnen des }
ti = imag[ip - 1] * ur + real[ip - 1] * ui; //{ aktuellen }
real[ip - 1] = real[i - 1] - tr; //{ 'Butterflys' }
imag[ip - 1] = imag[i - 1] - ti;
real[i - 1] = real[i - 1] + tr;
imag[i - 1] = imag[i - 1] + ti;
i = i + le;
}
ur = cos(M_PI * j / le1);
ui = -inv * sin(M_PI * j / le1);
}
}
if(!_hin){
for (i = 0; i <= Nmax - 1; i++)
{
real[i] = real[i] / (double)Nmax;
imag[i] = imag[i] / (double)Nmax;
}
}
} else {std::cout<<"FFT Hat nen Nullptr";}
//Betrag, Phase und Intervall
double df = 0.0, f=0.0, fg = 48000.0;
df = (fg / (float)Nmax);
int index = 1;
/* if(!_hin){
//while (f < 22000){
for(int index=0;index<real.size();index++){
f = index * df;
_Intervall->push_back(f);
real[index] = Betrag(index,_hin);
imag[index] = Phase(index);
//index = index + 1;
}
}*/
if (_hin) WriteFFT(_Name,&real,&imag,df);
for (int u=1;u<real.size();u++)
{
_data->at(u)=real.at(u);
}
_data->at(0)=real.at(1);
}
- Solution: *
void FFT::executeFFT(std::vector<double>* _real,std::vector<double>* _imag,std::vector<double>* _Intervall,std::string _Name)
{
if(_real !=nullptr|| real.empty() != true || imag.empty() != true){
if(_hin){
for (int i = 0; i < real.size(); i++)
{
//real[i] = 0.0;
imag[i] = 0.0;
real[i]=_real->at(i);
}
}else{ for (int i = 0; i < real.size(); i++)
{
real[i] = _real->at(i);
imag[i] = _imag->at(i);
}
}
int le, ip, m, i, nm1, j, t, le1, inv = 0;
double ur, ui, tr, ti, tmpr, tmpi, nv2, k;
if (_hin) inv = 1;
else inv = -1;
/*for (int i = 0; i <= Nmax - 2; i++)
{
real[i] = _data->at(i+1);
}*/
m = round((log(Nmax) / log(2)));
nv2 = Nmax / 2;
nm1 = Nmax - 1;
j = 1;
//Vertauschung der Eingangsfolge
for (i = 1; i <= nm1; i++)
{
if (i < j) {
tmpr = real[j - 1];
tmpi = imag[j - 1];
real[j - 1] = real[i - 1];
imag[j - 1] = imag[i - 1];
real[i - 1] = tmpr;
imag[i - 1] = tmpi;
}
k = nv2;
while (k < j)
{
j = round(j - k);
k = k / 2.0;
}
j = round(j + k);
}
//Berrechnung der Butterflys
for (int l = 1; l <= m; l = l + 1)
{
le = 1;
for (t = 1; t <= l; t = t + 1)
{
le = le * 2;
}
le1 = round(le / 2);
ur = 1;
ui = 0;
for (j = 1; j <= le1; j++)
{
i = j;
while (i <= Nmax)
{
ip = i + le1;
tr = real[ip - 1] * ur - imag[ip - 1] * ui; //{ Berechnen des }
ti = imag[ip - 1] * ur + real[ip - 1] * ui; //{ aktuellen }
real[ip - 1] = real[i - 1] - tr; //{ 'Butterflys' }
imag[ip - 1] = imag[i - 1] - ti;
real[i - 1] = real[i - 1] + tr;
imag[i - 1] = imag[i - 1] + ti;
i = i + le;
}
ur = cos(M_PI * j / le1);
ui = -inv * sin(M_PI * j / le1);
}
}
if(!_hin){
for (i = 0; i <= Nmax - 1; i++)
{
real[i] = real[i] / (double)Nmax;
imag[i] = imag[i] / (double)Nmax;
}
}
} else {std::cout<<"FFT Hat nen Nullptr";}
//Betrag, Phase und Intervall
double df = 0.0, f=0.0, fg = 48000.0;
df = (fg / (float)Nmax);
int index = 1;
_real=ℜ
_imag=&imag;
for (int u=1;u<real.size();u++) // u=0?
{
_real->at(u)=real.at(u);
_imag->push_back(imag.at(u));
}
xp = ifft(fft(x))
should hand you back anxp
that's almost equal tox
except for small differences due to rounding error within the FFT. $\endgroup$