Archive for March 2013
sinc interpolation and FFT transforms
implemented a oneshot FFT analysis and learned a few things, eg. that i really ought to install octave or similar. i may even be able to fool some innocent academics into disclosing methodology to me.
zero padded sample to 2^n of course. i’ve been having poor luck with getting the fft to do much beyond frequency shifting. i have tried several approaches to pitch shifting.
tried another approach.. i used sinc interpolation to apply the bins in cartesian form to the output array. this achieved the same results as changing the read speed of the sample, and repeated the signal for the length of the buffer when the pitch was raised. of course this process is then effectively useless, but encouraging to hear good sound quality for once. wish i could get on the same page with someone who has accomplished this hint hint.
it occured to me recently that sinc interpolation was not as intensive as it appeared – sine waves have two degrees of symmetry (if you like) and both can be exploited so that only one transcendental needs to be performed for every interpolation.. (perhaps easy to prove with a diagram). it is only necessary to discern the correct polarity of the first point you are calculating and create an extra variable to invert the operation between bins. quick copy and paste of a 32 point interpolation, hopefully you can sort it out.
for (i = 1; i <= nd2; i++) {
o = (float)i * shift; p = (int)o;
d = o – (float)p;
if (d == 0.f) {sleft[p] += ileft[i]; sright[p] -= iright[i];}
else {
s = sin(d * pi);
j = p – 15; if (j < 0) {j = 0; (p – j) % 2 ? m = -1 : m = 1;} else m = -1;
k = p + 17; if (k > nd2) k = nd2;
for (l = j; l < k; l++) {
o1 = (o – (float)l) * pi; o1 = m * s / o1;
sleft[l] += ileft[i] * o1; sright[l] -= iright[i] * o1;
m *= -1;
} }
}
for (i = nd2 + 1; i < n; i++) {
sleft[i] = 0;
sright[i] = 0;
}
i’ve never seen squat about this anywhere.. perhaps because it’s obvious if you have a moment to consider it. not knowing that the sinc function could be less expensive than a transcendental for every operation led me to avoid exploring solutions that employ it. now i know better.
*edit* notes that i didn’t copy the alg for bin 0.. of course 0 is not scaled so in this alg the values are just copied over, the “right” inverted cos this alg does the inversion 😉