Toque com valor real quando FFT de comprimento ímpar de preenchimento zero

13

Então, eu estou tentando escrever um interpolador no domínio da frequência que apague a resposta de frequência de um sinal e transforma inversas. Há dois casos com os quais tenho que lidar:

  1. Resposta uniforme - é necessário dividir a bandeja porque é ambígua. Então, copio a parte negativa do espectro e adiciono zeros no meio.Fs/2n*(interp-1)-1
  2. Resposta de comprimento ímpar - não há compartimento , basta dividir a frequência positiva / negativa e inserir zeros entre eles.Fs/2n*(interp-1)

O código que faz o preenchimento zero pode ser visto aqui

// 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));
    }
}

50.μs

50.μs

O canal imaginário tem uma pequena ondulação, mas não é tão ruim assim:

Fs/2Fs/2

gct
fonte
Seus gráficos são um pouco difíceis de ver desde que foram encolhidos.
Jason R
@ Jason desculpe, eu pensei que eles estavam ligados, eu ajustei o html para que eles possam clicar em tamanho real agora.
GCT
3
Você tem algum código ou arquivo de exemplo para o que está usando como entrada? Uma coisa a ter em mente é que as condições de contorno assumidas pela DFT. Especificamente, há uma suposição inerente de que o sinal de interesse é periódico. Portanto, se houver uma descontinuidade entre a primeira e a última amostra na entrada de comprimento ímpar, você poderá ver o toque como o que observou. É possível que a amostra uniforme seja mais contínua do começo ao fim, para que você não veja esse fenômeno.
Jason R
Não tenho dados em um formato que ninguém mais possa digerir facilmente, mas acho que você está certo. Acabei de chegar aqui para trabalhar e recompilar meu código / regenerar uma entrada de teste (10Hz-100Hz chirp em 1 segundo) e refazer a execução do código e não obtive o toque. Vi o seu comentário e alterei a frequência para 10-100.314 e agora vejo as transformações pares e ímpares.
Gt3
1
Você já tentou aplicar uma função de janela aos seus dados? Isso normalmente reduz o toque.
MarkSci

Respostas:

1

Ao zerar os compartimentos de alta frequência, você multiplicou efetivamente o espectro do sinal com uma função retangular. Multiplicação em frequência é convolução no tempo e o par de Fourier de um ret é sinc. Então, o que você realmente fez foi envolver o sinal do domínio do tempo com um sinc com a largura do lóbulo principal do sinc inversamente proporcional ao comprimento do ret. É por isso que as inúmeras técnicas de criação de filtros, como Parks-McClellan, são chamadas de "região de transição" ou banda de "transição", para que não ocorra uma alteração instantânea na resposta de frequência do filtro. Essas técnicas de design de filtro são importantes porque o filtro "ideal", como você usou, tem efeitos indesejáveis ​​no domínio do tempo.

user27575
fonte
0

Uma etapa no domínio da frequência será exibida como ondulações no domínio do tempo. Se você suavizar seus dados de frequência com uma função de janela (por exemplo, janela Hamming), deverá reduzir significativamente as ondulações.

Jian
fonte