Estou usando uma versão do "KISS FFT" de Mark Borgerding. Ele aceita uma matriz de valores de entrada de ponto fixo de 16 bits e produz uma matriz de resultados flutuantes de 32 bits.
Descobri que, se as amplitudes de entrada são baixas, muitos dos valores do resultado flutuante saem de zero, mas se eu simplesmente escalar as entradas (por, digamos, o fator 16), menos valores de saída serão zero e, portanto, a saída parece conter Mais detalhes. (Não que isso importe muito para meus propósitos, mas por consistência, divido os valores flutuantes resultantes pelo mesmo fator de escala.)
De qualquer forma, isso parece funcionar, em termos de produção de um resultado, quando anteriormente eu teria conseguido um buffer de praticamente todos os zeros, mas estou me perguntando se há algum motivo para não ser uma abordagem válida.
(Observe que essa abordagem significa que há muito mais "grossura" / granularidade nos dados e, em particular, o ruído de baixo nível que normalmente estaria presente não existe. Estou quase imaginando se seria prudente injetar algum ruído de baixo nível para substituir os valores zero na entrada.)
Respostas:
Essa pode ser uma abordagem válida. Você está observando um problema muito prático que surge frequentemente ao usar a aritmética de ponto fixo (ou seja, inteiro) (embora isso possa acontecer também no ponto flutuante). Quando o formato numérico que você está usando para executar cálculos não tem precisão suficiente para expressar toda a gama de valores que podem surgir dos seus cálculos, é necessária alguma forma de arredondamento (por exemplo, truncamento, arredondar para o mais próximo, etc.) em). Isso geralmente é modelado como um erro de quantização aditivo ao seu sinal.
No entanto, para algumas combinações de algoritmo e esquema de arredondamento, quando a magnitude do sinal de entrada é muito baixa, é possível obter o que você observou: um grande número de saídas zero. Basicamente, em algum lugar da sequência de operações, os resultados intermediários estão se tornando pequenos o suficiente para não quebrar o limite necessário para quantificar para um nível diferente de zero. O valor é arredondado para zero, o que geralmente pode se propagar para a saída. O resultado é, como você observou, um algoritmo que gera muitos zeros de saída.
Então, você pode contornar isso aumentando os dados? Às vezes (existem muito poucas técnicas que funcionam o tempo todo!). Se o seu sinal de entrada estiver delimitado em magnitude a um valor abaixo da escala completa do formato numérico (números inteiros assinados de 16 bits variam de -32768 a +32767), você poderá dimensionar o sinal de entrada para usar mais completamente o intervalo disponível para isto. Isso pode ajudar a mitigar os efeitos do erro de arredondamento, pois a magnitude de qualquer erro de arredondamento se torna menor em comparação com o sinal de interesse. Portanto, no caso em que todas as suas saídas estão sendo arredondadas para zeros internamente no algoritmo, isso pode ajudar.
Quando essa técnica pode machucá-lo? Dependendo da estrutura dos cálculos do algoritmo, aumentar o sinal de entrada pode expô-lo a estouros numéricos. Além disso, se o sinal contiver ruído ou interferência de fundo maior em magnitude do que o erro de arredondamento do algoritmo, a qualidade do que você obtém na saída será tipicamente limitada pelo ambiente, não pelo erro introduzido no cálculo.
fonte
A maneira mais fácil e mais fácil de lidar com isso é converter os dados em ponto flutuante ANTES da FFT e usar uma FFT de ponto flutuante. A única desvantagem dessa abordagem seria que você pode consumir mais processador e memória. Como sua saída é de ponto flutuante, provavelmente há pouca diferença prática.
fonte