Używam wersji „KISS FFT” Marka Borgerdinga. Akceptuje tablicę 16-bitowych wartości wejściowych o stałym punkcie i tworzy 32-bitową tablicę wyników liczb zmiennoprzecinkowych.
Odkryłem, że jeśli amplitudy wejściowe są niskie, wiele wartości liczb zmiennoprzecinkowych wychodzi na zero, ale jeśli po prostu skaluję dane wejściowe (powiedzmy, współczynnik 16), wówczas mniej wartości wyjściowych wynosi zero, a zatem wydaje się, że dane wyjściowe zawierają więcej szczegółów. (Nie dlatego, że ma to duże znaczenie dla moich celów, ale dla spójności dzielę następnie uzyskane wartości zmiennoprzecinkowe przez ten sam współczynnik skalowania.)
W każdym razie wydaje się, że to działa, jeśli chodzi o uzyskanie wyniku, gdy wcześniej otrzymywałem bufor praktycznie wszystkich zer, ale zastanawiam się, czy istnieje jakiś powód, dla którego może to nie być prawidłowe podejście.
(Należy zauważyć, że takie podejście oznacza, że w danych jest znacznie więcej „zgrubności” / ziarnistości, a w szczególności nie występuje szum niskiego poziomu, który normalnie występowałby. Prawie zastanawiam się, czy rozsądnie byłoby wstrzyknąć trochę hałasu niskiego poziomu, aby zastąpić zerowe wartości na wejściu.)
Odpowiedzi:
To może być prawidłowe podejście. Obserwujesz bardzo praktyczny problem, który pojawia się często przy stosowaniu arytmetyki stałoprzecinkowej (tj. Całkowitej) (chociaż może się to zdarzyć również w zmiennoprzecinkowym). Gdy format numeryczny, którego używasz do wykonywania obliczeń, nie ma wystarczającej precyzji, aby wyrazić pełny zakres wartości, które mogą wynikać z twoich obliczeń, wymagana jest jakaś forma zaokrąglania (np. Obcinanie, zaokrąglanie do najbliższego itd.) na). Jest to często modelowane jako addytywny błąd kwantyzacji twojego sygnału.
Jednak w przypadku niektórych kombinacji algorytmu i schematu zaokrąglania, gdy wielkość sygnału wejściowego jest bardzo niska, możliwe jest uzyskanie tego, co zaobserwowałeś: dużej liczby wyjść zerowych. Zasadniczo, gdzieś w sekwencji operacji, wyniki pośrednie stają się wystarczająco małe, aby nie przekroczyć progu wymaganego do kwantyzacji do niezerowego poziomu. Wartość jest następnie zaokrąglana do zera, co często może być propagowane do wyjścia. Wynikiem jest, jak zauważyłeś, algorytm, który generuje wiele zer wyjściowych.
Czy możesz więc obejść ten problem, zwiększając dane? Czasami (jest bardzo mało technik, które działają cały czas!). Jeśli Twój sygnał wejściowy jest ograniczony wielkością do wartości poniżej pełnej skali formatu liczbowego (liczby całkowite ze znakiem 16-bitowym działają w zakresie od -32768 do +32767), możesz skalować sygnał wejściowy w celu pełniejszego wykorzystania zakresu dostępnego dla to. Może to pomóc złagodzić skutki błędu zaokrąglenia, ponieważ wielkość każdego błędu zaokrąglenia staje się mniejsza w porównaniu z sygnałem zainteresowania. Tak więc, w przypadku, gdy wszystkie dane wyjściowe są zaokrąglane wewnętrznie do zer do algorytmu, może to pomóc.
Kiedy taka technika może cię zranić? W zależności od struktury obliczeń algorytmu zwiększenie skali sygnału wejściowego może narazić Cię na przepełnienia numeryczne. Ponadto, jeśli sygnał zawiera szum tła lub interferencję, która jest większa niż błąd zaokrąglenia algorytmu, wówczas jakość tego, co otrzymujesz na wyjściu, będzie zazwyczaj ograniczona przez środowisko, a nie błąd wprowadzany do obliczeń.
źródło
Najłatwiejszym i najgłupszym sposobem radzenia sobie z tym jest konwersja danych na zmiennoprzecinkowe PRZED FFT i użycie zmiennoprzecinkowego FFT. Jedynym minusem tego podejścia byłoby to, że możesz zużywać więcej procesora i pamięci. Ponieważ twój wynik i tak jest zmiennoprzecinkowy, prawdopodobnie nie ma praktycznej różnicy.
źródło