J'essaie donc d'écrire un interpolateur dans le domaine fréquentiel qui met à zéro la réponse en fréquence d'un signal et les transformations inverses. Il y a deux cas que je dois traiter:
- Réponse de longueur égale - il faut diviser le bac car il est ambigu. Je copie donc la partie négative du spectre et ajoute des zéros entre les deux.
n*(interp-1)-1
- Réponse de longueur impaire - il n'y a pas de bac il suffit donc de diviser la fréquence positive / négative et d'insérer des zéros entre eux.
n*(interp-1)
Le code qui fait le zéro-padding peut être vu ici
// 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));
}
}
Le premier cas fonctionne bien, je teste sur un signal chirp et interpole très bien, il y a un peu de bruit numérique, mais il est rond déclenché par une FFT Que pouvez - vous faire (premier ou si du signal spectacle):
Le canal imaginaire a une petite ondulation, mais pas aussi mauvais: