Suoneria a valore reale in caso di FFT a lunghezza dispari zero-padding


13

Quindi sto cercando di scrivere un interpolatore di dominio di frequenza che azzera la risposta in frequenza di un segnale e trasformazioni inverse. Ci sono due casi che devo affrontare:

  1. Risposta di lunghezza pari: devi dividere il cestino perché è ambiguo. Quindi copio la parte negativa dello spettro e aggiungo zeri nel mezzo.Fs/2n*(interp-1)-1
  2. Risposta lunghezza dispari - non c'è bin quindi basta dividere positivo / negativo della frequenza e inserto zeri tra loro.Fs/2n*(interp-1)

Il codice che esegue il padding zero può essere visto qui

// 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

Il canale immaginario ha una piccola increspatura, ma non altrettanto grave:

Fs/2Fs/2


Le tue trame sono un po 'difficili da vedere poiché sono state ridotte.
Jason R,

@Jason mi dispiace, ho pensato che fossero collegati, ho modificato l'html in modo che possano fare clic per ingrandirlo ora.
gct

3
Hai qualche codice o file di esempio per quello che stai usando come input? Una cosa da tenere a mente è che le condizioni al contorno assunte dal DFT. In particolare, si presume che il segnale di interesse sia periodico. Quindi, se c'è una discontinuità tra il primo e l'ultimo campione nell'input di lunghezza dispari, allora puoi vedere squillare come quello che hai osservato. È possibile che il campione di lunghezza pari sia più continuo dall'inizio alla fine, quindi non si vede questo fenomeno.
Jason R,

Non ho dati in un formato che chiunque altro potrebbe facilmente digerire, ma penso che tu abbia ragione. Sono appena arrivato qui per lavorare e ho ricompilato il mio codice / rigenerato un input di test (chirp 10Hz-100Hz per 1 secondo) e rieseguito il codice e non ho ricevuto il suono. Ho visto il tuo commento e ho cambiato la frequenza in 10-100.314 e ora vedo squillare su trasformazioni pari e dispari.
gct

1
Hai provato ad applicare una funzione finestra ai tuoi dati? Ciò ridurrà normalmente lo squillo.
MarkSci,

Risposte:


1

Azzerando i bin ad alta frequenza, è stato moltiplicato efficacemente lo spettro del segnale con una funzione rettangolare. La moltiplicazione in frequenza è una convoluzione nel tempo e la coppia di Fourier di un retto è un sinc. Quindi quello che hai fatto veramente è stato quello di convolgere il segnale nel dominio del tempo con un sinc con l'ampiezza del lobo principale del sinc inversamente proporzionale alla lunghezza del retto. Questo è il motivo per cui le numerose tecniche di progettazione del filtro come Parks-McClellan progettano quella che viene definita una "regione di transizione" o una banda di "transizione" in modo che non vi sia un cambiamento istantaneo nella risposta in frequenza del filtro. Queste tecniche di progettazione dei filtri sono importanti perché il filtro "ideale" come hai usato ha effetti indesiderati nel dominio del tempo.


0

Un passaggio nel dominio della frequenza verrà visualizzato come increspature nel dominio del tempo. Se leviga i dati di frequenza con una funzione di finestra (ad es. Finestra di Hamming), ciò dovrebbe ridurre significativamente le increspature.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.