Como reamostrar o áudio usando FFT ou DFT


12

Estou fazendo uma amostragem de áudio de voz executando primeiro uma FFT, depois obtendo apenas as partes do resultado necessárias e executando uma FFT inversa. No entanto, ele só funciona corretamente quando estou usando frequências com potência de dois, digamos, amostragem reduzida de 32768 a 8192. Eu executo uma FFT nos dados de 32k, descarto os 3/4 principais dos dados e, em seguida, faço uma FFT inversa nos restantes 1/4.

No entanto, sempre que tento fazer isso com dados que não estão alinhados corretamente, uma de duas coisas acontece: A biblioteca de matemática que estou usando (Aforge.Math) gera um ajuste, porque minhas amostras não são duas. Se eu tentar zerar as amostras para que elas se tornem poder de dois, fica sem sentido do outro lado. Também tentei usar um DFT, mas ele acaba sendo incrivelmente lento (isso precisa ser feito em tempo real).

Como eu iria zerar os dados da FFT corretamente, tanto na FFT inicial quanto na inversa no final? Supondo que eu tenho uma amostra em 44.1khz que precisa chegar a 16khz, atualmente eu tento algo assim, sendo a amostra 1000 em tamanho.

  1. Pad dados de entrada para 1024 no final
  2. Realizar FFT
  3. Leia os primeiros 512 itens em uma matriz (eu só preciso dos primeiros 362, mas preciso de ^ 2)
  4. Executar FFT inversa
  5. Leia os primeiros 362 itens no buffer de reprodução de áudio

A partir disso, recebo lixo no final. Fazer a mesma coisa, mas sem ter que preencher as etapas 1 e 3, devido ao fato de as amostras já serem ^ 2, fornece um resultado correto.

c#  audio 

9
FFT não é realmente o caminho certo para fazer isso. Você deseja um banco de filtros polifásicos para obter a máxima eficiência, mas se quiser apenas resolver o problema, primeiro faça o upsample para o GCD, depois passe baixo e depois faça downsample.
Bjorn Roche

Oi Bjorn: o que é "GCD"?
precisa saber é o seguinte

Respostas:


16

O primeiro passo é verificar se a taxa de amostragem inicial e a taxa de amostragem alvo são números racionais . Por serem números inteiros, são automaticamente números racionais. Se um deles não fosse um número racional, ainda seria possível alterar a taxa de amostragem, mas é um processo muito diferente e mais difícil.

O próximo passo é fatorar as duas taxas de amostra. A taxa de amostragem inicial, nesse caso, é 44100, que é fator . A taxa de amostragem alvo, 16000, é fator de 2 75 3 . Assim, para converter da taxa de amostragem inicial para a taxa de destino, devemos dizimar em 3 27 2 e interpolar em 2 552232527227533272255 .

As etapas anteriores devem ser executadas, não importa como você queira reamostrar os dados. Agora vamos falar sobre como fazer isso com FFT's. O truque para reamostrar com as FFTs é escolher comprimentos de FFT que façam tudo funcionar bem. Isso significa escolher um comprimento de FFT que seja múltiplo da taxa de dizimação (441, neste caso). Para o exemplo, vamos escolher um comprimento de FFT de 441, embora possamos ter escolhido 882 ou 1323 ou qualquer outro múltiplo positivo de 441.

Para entender como isso funciona, ajuda a visualizá-lo. Você começa com um sinal de áudio que parece, no domínio da frequência, algo como a figura abaixo. Taxa de amostragem de 44,1 kHz

Ao concluir o processamento, você deseja diminuir a taxa de amostragem para 16 kHz, mas deseja o mínimo de distorção possível. Em outras palavras, você simplesmente deseja manter tudo, desde a imagem acima, de -8 kHz a +8 kHz e largar todo o resto. Isso resulta na figura abaixo. insira a descrição da imagem aqui

Observe que as taxas de amostragem não estão em escala, elas estão lá apenas para ilustrar os conceitos.

255 ), por isso mantemos as 160 amostras que representam as frequências de -8 kHz a +8 kHz. Em seguida, invertemos a FFT nessas amostras e pronto! Você tem 160 amostras no domínio do tempo que são amostradas em 16 kHz.

Como você pode suspeitar, existem alguns problemas em potencial. Vou examinar cada uma delas e explicar como você pode superá-las.

  1. O que você faz se seus dados não são um múltiplo interessante do fator de dizimação? Você pode superar isso facilmente preenchendo o final dos dados com zeros suficientes para torná-lo um múltiplo do fator de dizimação. Os dados são preenchidos ANTES de serem enviados por FFT.

  2. eueu-1zeros (observe que o número de amostras de dados e o número de amostras de preenchimento devem AMBOS ser um múltiplo positivo do fator de dizimação - você pode aumentar o comprimento do preenchimento para atender a essa restrição), FFT usando os dados preenchidos, multiplicando o domínio da frequência dados e filtro e, em seguida, aliasing os resultados de alta frequência (> 8 kHz) para os resultados de baixa frequência (<8 kHz) antes de reduzir os resultados de alta frequência. Infelizmente, como a filtragem no domínio da frequência é um grande tópico por si só, não poderei entrar em mais detalhes nesta resposta. Eu direi, no entanto, que se você filtrar e estiver processando os dados em mais de um pedaço, precisará implementar Sobreposição e adição ou Sobreposição e economia para tornar a filtragem contínua.

Eu espero que isso ajude.

EDIT: A diferença entre o número inicial de amostras do domínio da frequência e o número alvo de amostras do domínio da frequência precisa ser uniforme, para que você possa remover o mesmo número de amostras do lado positivo dos resultados e do lado negativo dos resultados. No caso do nosso exemplo, o número inicial de amostras foi a taxa de dizimação, ou 441, e o número alvo de amostras foi a taxa de interpolação, ou 160. A diferença é 279, o que não é uniforme. A solução é dobrar o comprimento da FFT para 882, o que faz com que o número alvo de amostras também dobre para 320. Agora a diferença é uniforme e você pode descartar as amostras apropriadas do domínio da frequência sem problemas.


Muito agradável. Como você está fazendo figuras tão legais, Jim?
Spacey

@ Mohammad Eu costumo usar o Powerpoint. Nesse caso, usei a versão Libre Office do Powerpoint, que acredito ser chamada de "Impress".
Jim Clay

Olá, eu tenho uma pergunta sobre o seu ponto (2). O que você quer dizer exatamente nesta etapa: "... e, em seguida, o alias da alta frequência (> 8 kHz) resulta nos resultados de baixa frequência (<8 kHz) antes de abandonar os resultados de alta frequência". Eu entendo os passos antes disso. Depois de multiplicar meus dados do domínio f pelo domínio f do meu filtro, e depois? Além disso, esse método funciona se você deseja fazer um upsample de seus dados também? Obrigado.
TheGrapeBeyond

@TheGrapeBeyond Quando você alias no domínio do tempo, adiciona todas as zonas do Nyquist. Os primeiros elementos de todas as zonas de Nyquist são adicionados e se tornam o novo primeiro elemento da primeira zona de Nyquist. O segundo elemento de todas as zonas de Nyquist é adicionado e se torna o novo segundo elemento da primeira zona de Nyquist, etc.
Jim Clay

Hmm, não sei se entendi como você está realizando a reamostragem baseada em FFT, porque quando eu tento aqui, obtenho resultados muito estranhos. Eu vou fazer uma pergunta sobre isso.
TheGrapeBeyond

3

Embora a resposta acima esteja realmente completa:

Aqui está a essência disso:

  1. para reduzir a amostragem de um sinal, ele precisa ser um número inteiro. Antes da amostragem para baixo de um sinal, você precisa FILTRAR o sinal.
  2. você pode obter uma redução de número racional de amostras amostrando / interpolando o sinal primeiro.
  3. Upsampling é simplesmente inserir zeros e depois FILTRAR o sinal.
  4. para atingir 3/4 da taxa de amostragem. amplie o sinal inserindo 4 zeros entre cada amostra de sinal. Aplique um filtro. Em seguida, FILTRO o sinal e exclua a cada 3 de cada 4 amostras de sinal.

Detalhes sobre isso:

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

Além disso: a menos que seja absolutamente necessário, NÃO compute o FFT para calcular o IFFT. É um processo incrivelmente lento e considerado inadequado para a maioria das tarefas de processamento de sinal. a FFT é geralmente usada para analisar um problema ou aplicar o processamento de sinal apenas no domínio da frequência.


1

Como dizia Bjorn Roche, usar a FFT para isso seria terrivelmente ineficiente. Mas aqui vai de uma maneira muito, muito simples, usando o método de filtro de upsample e downsample no domínio da frequência.

1 - Pegue o sinal vetorial desejado de comprimento N.

2 - Execute o ponto N FFT.

3 - Preencher com zero a FFT com zeros de 160 * N no meio do vetor FFT.

4 - Realizar IFFT

5 - Selecione uma das 441 amostras descartando a outra 440.

Você ficará com um vetor de comprimento N * 160/441, que será o seu sinal reamostrado.

Como você pode ver, você está fazendo muitos cálculos inúteis, porque a maioria dos resultados será descartada. Mas se você tiver acesso ao código que executa a FFT, poderá ajustá-lo um pouco para calcular apenas os resultados IFFT com os quais você terminará e não os que você jogará fora.

Espero que ajude.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.