Come ricampionare l'audio usando FFT o DFT


12

Sto analizzando l'audio della voce eseguendo prima un FFT, quindi prendendo solo le parti del risultato di cui ho bisogno e quindi eseguendo un FFT inverso. Tuttavia, funziona correttamente solo quando utilizzo frequenze che sono entrambe di potenza pari a due, diciamo down-sampling da 32768 a 8192. Eseguo un FFT sui dati 32k, scarto i primi 3/4 dei dati e quindi eseguo un FFT inversa sul restante 1/4.

Tuttavia, ogni volta che provo a farlo con dati che non si allineano correttamente, accade una delle due cose: la libreria matematica che sto usando (Aforge.Math) genera un adattamento, perché i miei campioni non hanno una potenza di due. Se provo a azzerare i campioni in modo che diventino potenza di due, si ottiene senza senso dall'altra parte. Ho anche provato a usare un DFT, ma alla fine è follemente lento (questo deve essere fatto in tempo reale).

Come farei per azzerare correttamente i dati FFT, sia sulla FFT iniziale che sulla FFT inversa alla fine? Supponendo di avere un campione a 44.1khz che deve arrivare a 16khz, attualmente provo qualcosa del genere, il campione ha una dimensione di 1000.

  1. Pad dati di input a 1024 alla fine
  2. Esegui FFT
  3. Leggi i primi 512 articoli in un array (ho solo bisogno dei primi 362, ma ho bisogno di ^ 2)
  4. Eseguire FFT inversa
  5. Leggi i primi 362 elementi nel buffer di riproduzione audio

Da questo, alla fine, tiro fuori la spazzatura. Fare la stessa cosa ma senza dover eseguire il pad ai passaggi 1 e 3 a causa del fatto che i campioni sono già ^ 2, fornisce un risultato corretto.

c#  audio 

9
FFT non è davvero il modo giusto per farlo. Desideri un banco filtro polifase per la massima efficienza, ma se vuoi solo risolvere il problema, prima esegui l'upgrade al GCD, quindi passa basso, quindi downsample.
Bjorn Roche,

Ciao Bjorn: che cos'è "GCD"?
SpeedCoder5

Risposte:


16

Il primo passo è verificare che sia la frequenza di campionamento iniziale sia la frequenza di campionamento target siano numeri razionali . Poiché sono numeri interi sono automaticamente numeri razionali. Se uno di loro non fosse un numero razionale, sarebbe comunque possibile modificare la frequenza di campionamento, ma è un processo molto diverso e più difficile.

Il prossimo passo è di fattorizzare le due frequenze di campionamento. La frequenza di campionamento iniziale, in questo caso, è 44100, che varia in . La frequenza di campionamento target, 16000, viene calcolata su . Pertanto, per convertire dalla frequenza di campionamento iniziale alla frequenza target dobbiamo decimare di e interpolare di .2 75 3 3 27 2 2 552232527227533272255

I passaggi precedenti devono essere eseguiti indipendentemente da come si desidera ricampionare i dati. Ora parliamo di come farlo con FFT. Il trucco per ricampionare con FFT è quello di scegliere lunghezze FFT che fanno funzionare tutto bene. Ciò significa scegliere una lunghezza FFT che è un multiplo della velocità di decimazione (441, in questo caso). Per l'esempio, scegliamo una lunghezza FFT di 441, sebbene avremmo potuto scegliere 882, o 1323, o qualsiasi altro multiplo positivo di 441.

Capire come funziona aiuta a visualizzarlo. Si inizia con un segnale audio che assomiglia, nel dominio della frequenza, a qualcosa di simile alla figura seguente. Frequenza di campionamento di 44,1 kHz

Al termine dell'elaborazione, si desidera ridurre la frequenza di campionamento a 16 kHz, ma si desidera la minima distorsione possibile. In altre parole, vuoi semplicemente mantenere tutto dall'immagine sopra da -8 kHz a +8 kHz e rilasciare tutto il resto. Ciò si traduce nella foto qui sotto. inserisci qui la descrizione dell'immagine

Si noti che le frequenze di campionamento non sono in scala, sono solo lì per illustrare i concetti.

Il bello di scegliere una lunghezza FFT che è un multiplo del fattore di decimazione è che puoi ricampionare semplicemente facendo cadere porzioni del risultato FFT e quindi invertendo FFT ciò che rimane. Nel caso del nostro esempio hai 441 campioni di dati FFT, che ti danno 441 campioni complessi nel dominio della frequenza. Vogliamo decimare di 441 e interpolare di 160 ( ), quindi manteniamo i 160 campioni che rappresentano le frequenze da -8 kHz a +8 kHz. Quindi invertiamo FFT quei campioni e presto! Hai 160 campioni di dominio del tempo che sono campionati a 16 kHz.255

Come potresti sospettare, ci sono un paio di potenziali problemi. Esaminerò ciascuno di essi e spiegherò come superarli.

  1. Cosa fai se i tuoi dati non sono un bel multiplo del fattore di decimazione? Puoi facilmente superarlo riempiendo la fine dei tuoi dati con abbastanza zeri da renderli un multiplo del fattore di decimazione. I dati sono imbottiti PRIMA di essere FFT.

  2. Anche se il metodo che ho spiegato è molto semplice, è anche non ideale in quanto può introdurre squilli e altri cattivi artefatti nel dominio del tempo. Puoi evitarlo filtrando i dati del dominio di frequenza prima di eliminare i dati ad alta frequenza. Puoi farlo FFT con il filtro di lunghezza , riempiendo i tuoi dati (prima di farlo con FFT) con almenol - 1ll1zeri (si noti che il numero di campioni di dati e il numero di campioni di riempimento devono ENTRAMBI essere un multiplo positivo del fattore di decimazione; è possibile aumentare la lunghezza del riempimento per soddisfare questo vincolo), FFT''informando i dati imbottiti, moltiplicando il dominio della frequenza dati e filtri, quindi alias dei risultati ad alta frequenza (> 8 kHz) verso il basso nei risultati a bassa frequenza (<8 kHz) prima di far cadere i risultati ad alta frequenza. Sfortunatamente, dal momento che il filtraggio nel dominio della frequenza è un argomento importante a sé stante, non sarò in grado di approfondire in questa risposta. Dirò, tuttavia, che se si filtrano e si elaborano i dati in più di un blocco, sarà necessario implementare Overlap-and-Add o Overlap-and-Save per rendere il filtro continuo.

Spero che questo possa essere d'aiuto.

EDIT: la differenza tra il numero iniziale di campioni di dominio di frequenza e il numero target di campioni di dominio di frequenza deve essere pari in modo da poter rimuovere lo stesso numero di campioni dal lato positivo dei risultati come il lato negativo dei risultati. Nel caso del nostro esempio, il numero iniziale di campioni era il tasso di decimazione, o 441, e il numero target di campioni era il tasso di interpolazione, o 160. La differenza è 279, che non è pari. La soluzione è raddoppiare la lunghezza della FFT a 882, il che fa raddoppiare anche il numero target di campioni a 320. Ora la differenza è uniforme e puoi rilasciare i campioni di dominio di frequenza appropriati senza problemi.


Molto bella. Come stai facendo figure così belle al volo, Jim?
Spacey,

@Mohammad Di solito uso Powerpoint. In questo caso ho usato la versione di Powerpoint di Libre Office, che credo si chiama "Impress".
Jim Clay,

Ciao, ho una domanda sul tuo punto (2). Cosa intendi esattamente in questo passaggio: "... e quindi alias dei risultati ad alta frequenza (> 8 kHz) verso il basso nei risultati a bassa frequenza (<8 kHz) prima di far cadere i risultati ad alta frequenza". Comprendo i passaggi precedenti. Dopo aver moltiplicato i dati del mio dominio f con il dominio f del mio filtro, quindi cosa? Inoltre, questo metodo funziona anche se vuoi sottocampionare i tuoi dati? Grazie.
TheGrapeBeyond

@TheGrapeBeyond Quando si alias nel dominio del tempo, si sommano tutte le zone di Nyquist. I primi elementi di tutte le zone di Nyquist vengono sommati e diventano il nuovo primo elemento della prima zona di Nyquist. Il secondo elemento di tutte le zone di Nyquist viene sommato e diventa il nuovo secondo elemento della prima zona di Nyquist, ecc.
Jim Clay

Hmm, non sono sicuro di capire come stai facendo il ricampionamento basato su FFT, perché quando lo provo qui ottengo risultati molto strani. Farò una domanda al riguardo.
TheGrapeBeyond

3

Mentre la risposta sopra è davvero completa:

Ecco l'essenza:

  1. per sottocampionare un segnale deve essere un numero intero. Prima del campionamento verso il basso di un segnale, è necessario FILTRARE il segnale.
  2. puoi ottenere il downsampling di numeri razionali eseguendo prima il campionamento / interpolazione del segnale.
  3. Upsampling sta semplicemente inserendo zeri e quindi FILTRANDO il segnale.
  4. quindi per ottenere una frequenza di campionamento di 3/4. sovracampiona il segnale inserendo 4 zeri tra ogni campione di segnale. Applica un filtro. Quindi FILTRARE il segnale ed eliminare ogni 3 su 4 campioni di segnale.

Dettagli su questo:

http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/EE523_files/Ch_14_1%20Subband%20Intro%20&%20Multirate%20(PPT).pdf

Inoltre: a meno che non sia assolutamente necessario NON computerizzare la FFT per calcolare l'IFFT. È un processo incredibilmente lento ed è considerato inappropriato per la maggior parte delle attività di elaborazione del segnale. la FFT viene solitamente utilizzata per analizzare un problema o applicare l'elaborazione del segnale solo nel dominio della frequenza.


1

Come diceva Bjorn Roche, l'uso di FFT per questo sarebbe terribilmente insufficiente. Ma qui va in un modo molto semplice usando il metodo di upample filter e downsample nel dominio della frequenza.

1 - Prendi il segnale vettoriale desiderato di lunghezza N.

2 - Esegue il punto N FFT.

3 - Zero padd della FFT con 160 * N zeri al centro del vettore FFT.

4 - Eseguire IFFT

5 - Selezionare uno su 441 campioni scartando l'altro 440.

Ti verrà lasciato un vettore di lunghezza N * 160/441, che sarà il tuo segnale ricampionato.

Come puoi vedere, stai facendo molti calcoli inutili, perché la maggior parte dei risultati verrà quindi eliminata. Ma se hai accesso al codice che esegue FFT, potresti effettivamente modificarlo un po 'in modo che calcoli solo i risultati IFFT che finirai con e non quelli che getterai via.

Spero che sia d'aiuto.

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.