# Create a time signal with a known magnitude response

I am trying to construct a time signal that needs to have a known magnitude response.

The idea is to apply in Matlab/Octave an IFFT directly to the desired magnitude response: this corresponds to setting the real part equals to the magnitude response and the phase to zero.

The resulting time signal will be non-causal (half peak at the start/end of the buffer), so I am applying a bulk delay of half of buffer length, as you can see from the following image. Now, if I try to plot the desired and the derived magnitude responses, there are evedent differences in 10-100 Hz range, while in the other frequencies the two responses are almost identical. Why do I get these differences? The Matlab/Octave code I am using is the following, you can find the "h.mat" file here:

% Impulse response with the desired magnitude
% Desired magnitude
Hmag = abs(fft(h));
% Non-causal response
y = ifft(Hmag);
% Apply bulk delay
y_sh = circshift(y,length(y)/2);
figure; plot(y); hold on; plot(y_sh);
legend("non-causal","bulk delayed");
% Plot the two magnitude responses
fs = 48000;
NFFT = 32768;
f = linspace(0,fs,NFFT);
figure;
semilogx(f,20*log10(abs(fft(h,NFFT)))); hold on;
semilogx(f,20*log10(abs(fft(y_sh,NFFT))));


I am new to DSP so probably there are some naive errors in my implementation.

When you take the IFFT, you are specifying what the magnitudes are at the corresponding bin values, not between those bin values. If you want the two to responses to be more similar than they are, you could append zeroes to the end of ‘h’ after you load it but before you FFT it. This doesn’t change the magnitude response of ‘h’, but does increase the bin resolution. The more zeros you append, the closer the two magnitude responses will be, but the longer the impulse response.

For example, if you use fft(h, NFFT) for the desired magnitude, the two plots will be precisely equal, because you are calculating the response with the same resolution that you are plotting it with.

• The final impulse response needs to be limited to 2048 samples (I should have mentioned in the question). If I increase the zero padding of the desired response to 32768, y will have 32768 samples. I tried to cut the bulk delayed response y_sh to 2048 samples by applying a rectangular window centered in the peak, but the final plot has a big null near 40 Hz. Is there any other things I could try? Jul 8, 2021 at 19:32
• I see. You could try getting the impulse response with the higher resolution, truncating it down to the needed size, and the windowing with a different function. This will most likely get rid of the nulls, at the expense of accurate matching with the prototype magnitude response. When I’ve done this in the past I typically just try a few window functions and use the one I like. Jul 8, 2021 at 20:31

Shifting and padding are NOT commutative, i.e. order matters.

Shift first, than pad. Plot your unshifted data padded in the time domain and you will see why: It will have one peak at zero, another pea around 2000 and then a lot of zeros. This is probably not what you want

• I think I don't understand the answer. As suggested by @Dan Szabo, I am doing first Hmag = abs(fft(h,NFFT)) to increase the granularity of the desired magnitude response (zero-padding), then y = ifft(Hmag), then y_sh = circshift(y,length(y)/2) and finally windowing. If I am not wrong, I'm already working with a correct padded response, since I am padding the original impulse response with the desired magnitude. Jul 9, 2021 at 21:20
• Look at your code again. You do NOT pad before shiffting. You only pad for the plotting. Jul 10, 2021 at 19:34