É válido aumentar a amplitude (e presumivelmente a qualidade da FFT) simplesmente escalando os dados?

10

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.)

Daniel R Hicks
fonte
"Estou quase imaginando se seria sensato injetar algum ruído de baixo nível para substituir os valores zero na entrada". = en.wikipedia.org/wiki/Dither
endolith 15/05

Respostas:

7

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.

Jason R
fonte
Estou usando uma técnica dinâmica de dimensionamento que parece funcionar muito bem. E, por sorte, transitórios extremos são tratados como ruído e cortados de qualquer maneira, portanto, clipes ocasionais não devem ser um problema. Você acha que é válido "descalcificar" a saída dividindo pelo fator de escala da entrada?
Daniel R Hicks
1

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.

Hilmar
fonte
Recebi esse projeto com o algoritmo FFT atual já em vigor e estou relutante em mexer com ele neste momento. E tudo isso está acontecendo em um telefone, em tempo real, então o desempenho é definitivamente um problema.
Daniel R Hicks
Entendido. Você sabe se o FFT interno é fixo ou ponto flutuante? Se ele é fixo que você precisa se preocupar com recorte, estouro positivo e negativo
Hilmar
A documentação e os comentários são excepcionais em sua ausência, mas vejo muitas entradas no código e poucas preciosidades e duplas. Parece incluir a estrutura bruta #ifdef para alternar de 16 bits para 32 bits ou flutuante, mas aparentemente a estrutura foi desativada por muito tempo.
Daniel R Hicks
IPhone An (ARM + NEON CPU) pode fazer uma FFT flutuador mais rápido (através do quadro Acelerar) do que uma FFT inteiro em C.
hotpaw2