Domanda

Ho un flusso audio a 44Khz da un CD, rappresentato come un array di campioni PCM a 16 bit. Vorrei ridurlo a un flusso di 11 KHz. Come lo faccio? Dai miei giorni di lezione di ingegneria molti anni fa, so che lo stream non sarà più in grado di descrivere con precisione qualcosa a più di 5500Hz, quindi presumo di voler tagliare anche tutto al di sopra di quello. Qualche idea? Grazie.

Aggiornamento: c'è del codice su questa pagina che converte da 48 KHz a 8 KHz utilizzando un semplice algoritmo e un array di coefficienti che assomiglia a {1, 4, 12, 12, 4, 1}. Penso che sia quello di cui ho bisogno, ma ne ho bisogno per un fattore 4x anziché 6x. Qualche idea su come vengono calcolate queste costanti? Inoltre, finisco per convertire comunque i campioni da 16 byte in float, quindi posso eseguire il downsampling con float anziché con short, se ciò aiuta la qualità a tutti.

È stato utile?

Soluzione

Leggi i filtri FIR e IIR. Questi sono i filtri che utilizzano un array coerente.

Se esegui una ricerca su Google su " Progettazione filtri FIR o IIR " troverai un sacco di software e applet online che fanno il duro lavoro (ottenendo i coefficienti) per te.

Modifica

Questa pagina qui ( http: //www-users.cs. york.ac.uk/~fisher/mkfilter/ ) ti consente di inserire i parametri del tuo filtro e sputerà pronto per usare il codice C ...

Altri suggerimenti

Hai ragione nel dover applicare il filtro passa-basso sul tuo segnale. Qualsiasi segnale superiore a 5500 Hz sarà presente nel segnale in downsampling ma "aliasato" come un'altra frequenza, quindi dovrai rimuoverli prima del downsampling.

È una buona idea fare il filtro con float. Esistono anche algoritmi di filtro a punti fissi, ma quelli generalmente hanno compromessi di qualità per funzionare. Se hai i float, usali!

L'uso dei DFT per il filtraggio è generalmente eccessivo e rende le cose più complicate perché le dft non sono un processo continuo ma funzionano sui buffer.

I filtri digitali generalmente hanno due gusti. FIR e IIR. Generalmente sono la stessa idea, ma i filtri IIF utilizzano circuiti di feedback per ottenere una risposta più rigida con coefficienti molto inferiori. Questa potrebbe essere una buona idea per il downsampling perché è necessaria una pendenza del filtro molto ripida.

Il downsampling è una specie di caso speciale. Poiché hai intenzione di buttare via 3 campioni su 4, non è necessario calcolarli. Esiste una classe speciale di filtri per questo chiamato filtri polifase.

Prova a cercare su Google la polifase IIR o la FIR polifase per ulteriori informazioni.

Si noti (in aggiunta agli altri commenti) che l'approccio semplice-facile-intuitivo " esegue il downsample di un fattore 4 sostituendo ogni gruppo di 4 campioni consecutivi con il valore medio " ;, non è ottimale ma non è tuttavia sbagliato, né praticamente né concettualmente. Perché la media equivale precisamente a un filtro passa-basso (una finestra rettangolare, che corrisponde a una frequenza sinc). Ciò che sarebbe concettualmente sbagliato è di sottocampionare semplicemente prendendo uno di ciascuno dei 4 campioni: ciò introdurrebbe sicuramente l'aliasing.

A proposito: praticamente qualsiasi software che esegua un nuovo ricampionamento (audio, immagine o altro; esempio per il caso audio: sox) ne tiene conto e spesso consente di scegliere il filtro passa-basso sottostante.

È necessario applicare un filtro passa-basso prima di sottocampionare il segnale per evitare "aliasing". La frequenza di taglio del filtro passa-basso dovrebbe essere inferiore alla frequenza di nyquist, che è la metà della frequenza di campionamento.

Il processo che hai chiamato " Decimation " ;. Ci sono 2 passaggi:

  1. Applicazione del filtro passa-basso sui dati (nel tuo caso LPF con Cut Off a Pi / 4).
  2. Downsampling (nel tuo caso prelevare 1 campione su 4).

Esistono molti metodi per progettare e applicare il filtro passa basso.

Puoi iniziare qui:

http://en.wikipedia.org/wiki/Filter_design

È possibile utilizzare libsamplerate per eseguire il sollevamento di carichi pesanti. Libsamplerate è un'API C e si occupa del calcolo dei coefficienti di filtro. Puoi scegliere tra diversi filtri di qualità in modo da poter scambiare la qualità con la velocità.

Se preferisci non scrivere alcun codice, puoi semplicemente utilizzare Audacity per eseguire la conversione della frequenza di campionamento . Offre una potente interfaccia grafica e utilizza libsamplerate per la conversione della frequenza di campionamento.

Proverei ad applicare DFT, tagliando 3/4 del risultato e applicando DFT inverso. Non so dire se suonerà bene senza davvero impegnarsi.

Il "migliore" la soluzione possibile è davvero un DFT, scartando i primi 3/4 delle frequenze ed eseguendo un DFT inverso, con il dominio limitato al quarto inferiore. Scartare i primi 3 / 4s è un filtro passa-basso in questo caso. Il riempimento con una potenza di 2 numero di campioni probabilmente ti darà un vantaggio in termini di velocità. Tuttavia, tieni presente come il tuo pacchetto FFT memorizza i campioni. Se si tratta di una FFT complessa (che è molto più facile da analizzare e generalmente ha proprietà più piacevoli), le frequenze passeranno da -22 a 22 o da 0 a 44. Nel primo caso, si desidera il 1/4 di mezzo. In quest'ultimo, il più esterno 1/4.

Puoi fare un lavoro adeguato calcolando la media dei valori campione insieme. Il modo ingenuo di afferrare campioni quattro per quattro e fare una media ponderata uguale funziona, ma non è troppo grande. Invece ti consigliamo di utilizzare un " kernel " funzione che li media insieme in modo non intuitivo.

Mathwise, scartare tutto al di fuori della banda di bassa frequenza è la moltiplicazione per una funzione box nello spazio di frequenza. La trasformata (inversa) di Fourier trasforma la moltiplicazione puntuale in una convoluzione delle trasformazioni (inverse) di Fourier delle funzioni e viceversa. Quindi, se vogliamo lavorare nel dominio del tempo, dobbiamo eseguire una convoluzione con la funzione (inversa) di Fourier della funzione box. Questo risulta essere proporzionale al "sinc" funzione (sin a) / at, dove a è la larghezza della casella nello spazio delle frequenze. Quindi in ogni 4a posizione (dato che stai effettuando il downsampling di un fattore 4) puoi sommare i punti vicini ad essa, moltiplicati per sin (a dt) / a dt, dove dt è la distanza nel tempo a quella posizione. Quanto vicino? Bene, dipende da quanto vuoi che suoni. È comune ignorare tutto al di fuori del primo zero, ad esempio, o semplicemente prendere il numero di punti per essere il rapporto con il quale si effettua il downsampling.

Finalmente c'è il modo povero (ma veloce) di scartare la maggior parte dei campioni, mantenendo solo lo zeroth, il quarto e così via.

Onestamente, se si adatta alla memoria, consiglierei di seguire la rotta DFT. Se non utilizza uno dei pacchetti di filtri software che altri hanno consigliato di creare per te il filtro.

Di recente mi sono imbattuto in BruteFIR che potrebbe già fare qualcosa sei interessato?

Devi applicare un filtro passa-basso (rimuovendo le frequenze sopra i 5500 Hz) e quindi applicare la decimazione (lasciare ogni nesima campionatura, ogni quarta nel tuo caso).

Per la decimazione, vengono normalmente utilizzati filtri FIR, non IIR, poiché non dipendono dalle uscite precedenti e quindi non è necessario calcolare nulla per i campioni scartati. Gli IIR, generalmente, dipendono sia dagli input che dagli output, quindi, a meno che non venga utilizzato un tipo specifico di IIR, dovresti calcolare ogni campione di output prima di scartarne 3/4.

Ho appena cercato su Google un articolo introduttivo sull'argomento: https: // www. dspguru.com/dsp/faqs/multirate/decimation

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top