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.
- Pad dados de entrada para 1024 no final
- Realizar FFT
- Leia os primeiros 512 itens em uma matriz (eu só preciso dos primeiros 362, mas preciso de ^ 2)
- Executar FFT inversa
- 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.
Respostas:
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 7 ∗ 5 3 . Assim, para converter da taxa de amostragem inicial para a taxa de destino, devemos dizimar em 3 2 ∗ 7 2 e interpolar em 2 5 ∗ 522* 32∗ 52* 72 27∗ 53 32* 72 25∗ 5 .
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.
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.
Observe que as taxas de amostragem não estão em escala, elas estão lá apenas para ilustrar os conceitos.
Como você pode suspeitar, existem alguns problemas em potencial. Vou examinar cada uma delas e explicar como você pode superá-las.
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.
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.
fonte
Embora a resposta acima esteja realmente completa:
Aqui está a essência disso:
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.
fonte
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.
fonte