Sunday, 2 August 2015

interpolation - 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?




No comments:

Post a Comment

readings - Appending 内 to a company name is read ない or うち?

For example, if I say マイクロソフト内のパートナーシップは強いです, is the 内 here read as うち or ない? Answer 「内」 in the form: 「Proper Noun + 内」 is always read 「ない...