Est-il valable d'augmenter l'amplitude (et vraisemblablement la qualité FFT) en mettant simplement à l'échelle les données?


10

J'utilise une version de "KISS FFT" de Mark Borgerding. Il accepte un tableau de valeurs d'entrée à virgule fixe 16 bits et produit un tableau de résultats flottants 32 bits.

J'ai découvert que si les amplitudes d'entrée sont faibles, beaucoup des valeurs de résultat flottantes sortent à zéro, mais si je modifie simplement les entrées (par, disons, le facteur 16), alors moins de valeurs de sortie sont nulles et donc la sortie semble contenir plus de détails. (Ce n'est pas important pour moi, mais pour des raisons de cohérence, je divise ensuite les valeurs flottantes résultantes par le même facteur d'échelle.)

Quoi qu'il en soit, cela semble fonctionner, en termes de production d'un résultat alors qu'auparavant je venais d'obtenir un tampon de pratiquement tous les zéros, mais je me demande s'il y a une raison pour laquelle ce ne serait pas une approche valide.

(Notez que cette approche signifie qu'il y a beaucoup plus de "grossièreté" / granularité dans les données, et, en particulier, le bruit de bas niveau qui serait normalement présent ne l'est pas. Je me demande presque s'il serait sage d'injecter du bruit de faible niveau pour remplacer les valeurs nulles dans l'entrée.)


"Je me demande presque s'il serait judicieux d'injecter du bruit de bas niveau pour remplacer les valeurs nulles dans l'entrée." = en.wikipedia.org/wiki/Dither
endolith

Réponses:


7

Cela peut être une approche valable. Vous observez un problème très pratique qui se pose souvent lors de l'utilisation de l'arithmétique à virgule fixe (c'est-à-dire entier) (bien que cela puisse également se produire en virgule flottante). Lorsque le format numérique que vous utilisez pour effectuer des calculs n'a pas assez de précision pour exprimer toute la plage de valeurs pouvant résulter de vos calculs, une forme d'arrondi est requise (par exemple, troncature, arrondi au plus proche, etc.) sur). Ceci est souvent modélisé comme une erreur de quantification additive de votre signal.

Cependant, pour certaines combinaisons d'algorithme et de schéma d'arrondi, lorsque la magnitude du signal d'entrée est très faible, il est possible d'obtenir ce que vous avez observé: un grand nombre de sorties nulles. Fondamentalement, quelque part dans la séquence des opérations, les résultats intermédiaires deviennent suffisamment petits pour ne pas franchir le seuil requis pour quantifier à un niveau différent de zéro. La valeur est ensuite arrondie à zéro, ce qui peut souvent se propager vers la sortie. Le résultat est, comme vous l'avez noté, un algorithme qui génère beaucoup de zéros de sortie.

Pouvez-vous contourner cela en augmentant les données? Parfois (il y a très peu de techniques qui fonctionnent tout le temps!). Si votre signal d'entrée est limité en amplitude à une valeur inférieure à la pleine échelle du format numérique (les entiers signés 16 bits vont de -32768 à +32767), alors vous pouvez mettre à l'échelle le signal d'entrée pour utiliser plus pleinement la plage disponible pour il. Cela peut aider à atténuer les effets de l'erreur d'arrondi, car l'amplitude de toute erreur d'arrondi devient plus petite par rapport au signal d'intérêt. Donc, dans le cas où toutes vos sorties sont arrondies à zéro en interne à l'algorithme, cela peut aider.

Quand une telle technique peut-elle vous blesser? En fonction de la structure des calculs de l'algorithme, l'augmentation du signal d'entrée peut vous exposer à des débordements numériques. De plus, si le signal contient un bruit de fond ou des interférences d'une amplitude supérieure à l'erreur d'arrondi de l'algorithme, la qualité de ce que vous obtenez à la sortie sera généralement limitée par l'environnement, et non par une erreur introduite dans le calcul.


J'utilise une technique dynamique de mise à l'échelle qui semble assez bien fonctionner. Et, comme par hasard, les transitoires extrêmes sont traités comme du bruit et écrêtés de toute façon, donc l'écrêtage occasionnel ne devrait pas être un problème. Pensez-vous qu'il soit valable de «détartrer» la sortie en la divisant par le facteur d'échelle de l'entrée?
Daniel R Hicks

1

Le moyen le plus simple et le plus sûr pour y faire face est de convertir les données en virgule flottante AVANT la FFT et d'utiliser une FFT en virgule flottante. Le seul inconvénient de cette approche est que vous pouvez consommer plus de processeur et de mémoire. Comme votre sortie est de toute façon en virgule flottante, il y a probablement peu de différence pratique.


On m'a confié ce projet avec l'algorithme FFT actuel déjà en place, et je suis réticent à le foutre en l'air à ce stade. Et tout cela se passe sur un téléphone, en temps réel, donc les performances sont définitivement un problème.
Daniel R Hicks

Compris. Savez-vous si la FFT interne est à virgule fixe ou flottante? Si le problème est résolu, vous devez vous soucier de l'écrêtage, du débordement et du débordement
Hilmar

La documentation et les commentaires sont exceptionnels en son absence, mais je vois beaucoup d'ints dans le code et quelques précieux flotteurs et doubles. Il semble inclure le cadre brut #ifdef pour passer de 16 bits à 32 bits ou float, mais le cadre a apparemment été désactivé depuis longtemps.
Daniel R Hicks

Un iPhone (ARM + NEON CPU) peut faire une FFT flottante plus rapidement (via le framework Accelerate) qu'une FFT entière en C.
hotpaw2
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.