# Real-valued ringing when zero-padding odd-length FFT

So I'm trying to write a frequency-domain interpolator that zero-pads the frequency response of a signal and inverse transforms. There's two cases I have to deal with:

1. Even-length response - have to split the $F_s/2$ bin because it's ambiguous. So I copy the negative part of the spectrum, and add n*(interp-1)-1 zeros in between.
2. Odd-length response - there is no $F_s/2$ bin so just split positive/negative frequency and insert n*(interp-1) zeros between them.

The code that does the zero-padding can be seen here

// Copy negative frequency components to end of buffer and zero out middle
//  inp    - input buffer of complex floats
//    n    - transform size
//  interp - interpolation amount
void zero_pad_freq(cfloat_t *inp, size_t n, size_t interp) {
if ((n % 2) == 0) {
memmove(inp + n*interp - n/2, inp + n/2,     n/2*sizeof(cfloat_t));
memset (inp + n/2 + 1, 0,       (n*(interp-1)-1)*sizeof(cfloat_t)); // Duplicate Fs/2 so we need one less zero

inp[n/2]          /= 2.0;
inp[n*interp-n/2] /= 2.0;
} else {
memmove(inp + n*interp - n/2, inp + (n+1)/2, n/2*sizeof(cfloat_t));
memset (inp + (n+1)/2, 0,         (n*(interp-1))*sizeof(cfloat_t));
}
}

The first case is working fine, I'm testing it on a chirp signal and it interpolates just fine, there's a little numeric noise, but it's round tripped through an FFT so what can you do (first $50 \mu s$ or so of the signal show):

The problem is with the odd-length transform, I'm getting a pretty heinous transient response on the real samples only ($50 \mu s$ again, real):

The imaginary channel has a small ripple on it, but not nearly as bad:

It's like I've screwed up my $F_s/2$ bin in the odd case, but there is no $F_s/2$ bin, so I'm very puzzled. Anyone have any thoughts?

• Your plots are a bit hard to see since they've been shrunk. – Jason R Dec 3 '12 at 17:00
• @Jason sorry I thought they were linked, I tweaked the html so they can clicked for full-size now. – gct Dec 3 '12 at 17:19
• Do you have any code or example file for what you're using as the input? One thing to keep in mind is that the boundary conditions assumed by the DFT. Specifically, there is an inherent assumption that the signal of interest is periodic. So, if there is a discontinuity between the first and last samples in the odd-length input, then you can see ringing like what you observed. It's possible that the even-length sample is more continuous from start to end, so you don't see this phenomenon. – Jason R Dec 3 '12 at 17:44
• I don't have data in a format anyone else'd be able to easily digest, but I think you're right. I just got here to work and recompiled my code/regenerated a test input (10Hz-100Hz chirp over 1 second) and re-ran the code and didn't get the ringing. I saw your comment and changed the frequency to 10-100.314 and I see ringing on both even and odd transforms now. – gct Dec 3 '12 at 18:11
• Have you tried applying a window function to your data? That will normally reduce the ringing. – MarkSci Mar 18 '15 at 18:16