logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.
  • #1 2634295
    Benyman
    Poziom 11  
    Witam wszystkich serdecznie ;)

    Mam pytanko ;)

    Napisalem sobie algorytm do oblicznia fft,liczy spoczko ;)
    Chcialbym teraz narysowac widmo sygnalu.Z osia czestotliwosci nie ma problemu ba wiem jak wyznaczac wartosci czestotliwosci dla kolejnych prazkow jednak nie wiem co zrobic ze skala amplitudy.
    Chcialbym amlitude rysowac w skali dB,lub jak sie nazywa to w programach dzwiekowych dBFS tylk nie wiem jak sie to przelicza.

    Pozdrawiam i dziekuje za odpowiedzi ;)
  • #2 2634838
    shg
    Poziom 35  
    A no przelicza się dość prosto.
    Jeżeli X jest w skali liniowej, czyli wysokość prążka, którą otrzymujesz z FFT, to żeby przedstawić X w skali logarytmicznej robisz tak:

    x = 20 * log(X)

    Tylko na jedną rzecz trzeba uważać, jeżeli X = 0, to nie wyliczysz logarytmu i przed liczeniem trzeba to sprawdzić i przypisać x'owi jakąś wartość, w opcji "full wypas" sprawdzasz nie tylko czy X jest zerem, ale też, czy nie znajduje się poniżej jakiegoś minimalnego poziomu reprezentowanego przez skalę logarytmiczną (po angielsku to intercept level, a po polsku nie wiem :P)

    Jeżeli liczysz FFT z próbek N bitowych to Intercept level znajduje się na poziomie:
    ildb = -20 * log(2^N) [dB], lub w skali liniowej:
    ill = 1 / (2^N)

    czyli w sumie zamiana na skalę logarytmiczną wygląda tak:
    ill  = 1 / (2^N)
    /* dla wszystkich pasm po kolei: */
    if(X < ill)
      x = 0;
    else
      x = 20 * log(X);
    


    Oczywiście założenie numer jeden jest takie, że wyniki FFT masz już przeliczony na postać polarną (informacje o fazie sygnału można pominąć w obliczeniach, bo jest tu niepotrzebna, a obliczenie jej pożera trochę czasu)
    I założenie numer siedem. Wartości z FFT zostały przeskalowane do zakresu 0..1.
    Jeżeli nie, to aby otrzymać wynik w dBFS według powyższych wzorów należy te wartości do takiego zakresu przeskalować.

    Jest też trochę możliwości optymalizacji, ponieważ zamiana wyniku FFT na postać polarną wymaga liczenia pierwiastka, a potem zamiana na postać logarytmiczną - liczenia logarytmu.

    Można sobie uprocić, ponieważ:
    $$\log_{10} X = \frac{1}{\ln 10} \cdot \ln X$$
    gdzie:
    $$X = \sqrt{Re^2 + Im^2} = (Re^2 + Im^2)^{\frac{1}{2}}$$
    i:
    $$\ln (X^a) = a \cdot ln X$$
    więc wydajniejsza formułka na skalę logarytmiczną przyjmuje postać:
    $$x = 20 \cdot \frac{1}{\ln 10} \cdot \frac{1}{2} \cdot \ln(Re^2 + Im^2)$$
  • #3 2636583
    Benyman
    Poziom 11  
    shg wielkie dzieki za odpowiedz ;)

    Mam jednak kilka pytan bo nie bardzo kapuje ;)

    Zauwazylem ze w programach do analizy dzwieku skale logarytmiczne rozkladaja sie w przedziale od ok -150 do 0 dB lub dBFS bo nie wiem jak to dokladnie jest a zgodnie z wzorem
    ildb = -20 * log(2^N) [dB]

    najminiejszy prog wynosilby dla 1024 probek(tyle probek wrzucam do fft) ok -6135 wiec albo czegos nie rozumiem albo zle licze ;)

    i dalej wzor

    x = 20 * log(X);

    tez jakos mi nie pasuje,albo znow nie rozumiem ;)

    dla wartosci 7000 bo taka jest w przyblizeniu najwieksza moc prozkow(przewaznie prazki o niskich czestotliwosciach do 200 Hz) zgodni z wzorem dalaby mi wartosc

    20 * log(7000)=~ 77 dB nie wiem czy to dobrze czy nie ;(

    Shg prosze odpisz mi jak to jest dokladnie i czy dobrze kombinuje.Popraw mnie jezeli trzeba ;)

    Jeszcze raz dzieks za odpowiedz pozdrawiam ;)
  • #4 2636839
    shg
    Poziom 35  
    Benyman napisał:
    Zauwazylem ze w programach do analizy dzwieku skale logarytmiczne rozkladaja sie w przedziale od ok -150 do 0 dB lub dBFS bo nie wiem jak to dokladnie jest a zgodnie z wzorem
    ildb = -20 * log(2^N) [dB]

    Ano wszystko się zgadze, a te -150dB to jest na przykład dla tego, że programy do obróbki dźwięku zazwyczaj operują na większej precyzji, przez co poziom szumu się obniża, ai dajemy intercept level taki, żeby uchwycić sygnały na poziomie szumu i wyżej. Ponadto programy te liczą zazwyczaj FFT na liczbach zmiennoprzecinkowych i dla takich też liczb wykonują okienkowanie, przez co efektywny poziom szumów spada o ok6dB (zależy od okienka).

    Benyman napisał:
    najminiejszy prog wynosilby dla 1024 probek(tyle probek wrzucam do fft) ok -6135 wiec albo czegos nie rozumiem albo zle licze ;)

    N to nie liczba próbek, a rozdzielczość z jaką zapisana jest próbka.
    czyli dla szesnastobitowych próbek N=16, a intercept level ustawia się na poziomie -96dB, jest to poziom szumów kwantyzacji dla 16 bitów, poniżej tego poziomu nie odróżnisz sygnału od szumu, więc nie ma sensu nawet tego wyświetlać. A jeżeli masz sygnałjako liczba zmiennoprzecinkowa, to nie ma co kombinować i po prostu przyjmuj, że poziom szumów nie będzie leżał niżej niż te 150dB, o ile tylko sygnał nie pochodzi z aparatury pracującej w temperaturze bliskiej 0 K. W typowych warunkach (pokojowych) taką bardzo trudną do przekroczenia granicą jest -120dB, a w zasadzie nieprzekraczalną -140dB

    Benyman napisał:
    i dalej wzor
    x = 20 * log(X);
    tez jakos mi nie pasuje,albo znow nie rozumiem ;)

    dla wartosci 7000 bo taka jest w przyblizeniu najwieksza moc prozkow(przewaznie prazki o niskich czestotliwosciach do 200 Hz) zgodni z wzorem dalaby mi wartosc

    20 * log(7000)=~ 77 dB nie wiem czy to dobrze czy nie ;(

    Wszystko jest w porządku.
    Jak napisałem uprzednio, jeżeli z FFT otrzymujesz wartości większe od 1, to wyniki należy przeskalować do zakresu 0..1.
    Czyli jeżeli maksymalną TEORETYCZNĄ wartością otrzymaną z FFT jest u Ciebie powiedzmy 8192, to wartości wszystkich prążków należy przez 8192 podzielić i dopiero liczyć logarytmy.
    a dBFS to dB Full Scale, czyli poziom sygnału w stosunku do maksymalnej wartości wyrażony w dB. Wartość ta może być tylko mniejsza lub równa zero, więcej od zera oznaczało by, że poziom sygnału przekracza teoretyczne możliwe maksimum, czyli coś nie tak :P

    Inaczej można to zapisać tak:
    FS = 8192 /* max. teoretyczna wartość, jaką można otrzymać z FFT */
    N = 16 /* rozdzielczość, czyli ilość bitów na próbkę */
    il = 1 / (2^N) /* '^' to nie Exclusive OR, tylko potega :P */
    
    /* dla wszystkich prazkow (X) po kolei:*/
    x = 20 * log(X / FS) /* X pod logarytmem zostaje znormalizowane do przedzialu 0..1 */
    
  • #5 2637158
    Benyman
    Poziom 11  
    Jeszcze raz dzieks za odpowiedz ;)

    Olsnienia doszedlem rano gdy otworzyle oczy heheh Jednak wyprzedziles mnie z odpowiedzia ;)

    Jak czlowiek zmeczony po calym dniu pracy to glupoty sie go trzymaja heheheh

    Jeszcze raz dzieki udzieliles mi fachowej pomocy za co bardzo dziekuje ;)

    Pozdrawiam ;)

    Dodano po 41 [minuty]:

    Shg mam jeszcze jedno pytanko ;)

    NIe wiesz moze jak uzyskac skale dB dla wartosci amplitud przed obliczeniami FFT?

    Doszedlem do wniosku ze zrobil bym tez wykres fali.No i jak wiesz dla pliku 16 bitowego beda to wartosci ~ -32000 - 32000 dla 8 bitowego 0 -255 tak jest dla wava

    teraz nie wiem znow jak przeskalowac to na dB ;)

    Pewno wiesz jak to zrobic :d

    Prosze pomoz ... pozdrawiam.

    Dodano po 36 [sekundy]:

    Shg mam jeszcze jedno pytanko Wink

    NIe wiesz moze jak uzyskac skale dB dla wartosci amplitud przed obliczeniami FFT?

    Doszedlem do wniosku ze zrobil bym tez wykres fali.No i jak wiesz dla pliku 16 bitowego beda to wartosci ~ -32000 - 32000 dla 8 bitowego 0 -255 tak jest dla wava

    teraz nie wiem znow jak przeskalowac to na dB Wink

    Pewno wiesz jak to zrobic :d

    Prosze pomoz ... pozdrawiam.
  • #6 2637868
    shg
    Poziom 35  
    Hmmm. jak chcesz wykres, jak z oscyloskopu, to się robi w skali liniowej.
    no chyba, ze VU-meter, czy inszy wskaznik poziomu.
    Na dB przeliczasz tak samo, też trzeba to przeskalować do zakresu 0..1.

    Różnica polega na tym, że najpierw trzeba sobie policzyć wartość amplitudy, metod jest kilka, najprościej wyliczyć wartość bezwzględną dla każdej próbki. Z innych metod to na przykład obliczanie wartości skurecznej (RMS). Bierzemy ileśtam próbek, podnosimy każdą do kwadratu, potem liczymy z tego średnią i pierwiastkujemy.

    dla próbek ośmio bitowych uzyskamy wartości z zakresu 0..128, dla 16 bitowych 0..32768 i przez górną granicę trzeba wszystkie wartości podzielić.

    Co do ośmiobitowych .wav, to rzecz wygląda tak, że wystarczy od każdej próbki odjąć 128, żeby uzyskać zapis 'ze znakiem'. Ale do rysowania wykresu a la oscyloskop wygodniejsza jest postać bez znaku, dokładnie tak, jak dane zapisane są w pliku.
    Natomiat o ile dobrze pamiętam, to dla próbek 16 bitowych wygląda to dokładnie tak samo, czyli zapisane są jako liczby z zakresu 0..65535, w takim wypadku należy oczywiście odjąć 32768.
  • #7 2641881
    Benyman
    Poziom 11  
    ok ;)

    Shg dzieki bardzo za odpowiedzi.

    Teraz sie mecze jak to ladnie rysowac.
    Wrazie jakis problemow bede sie jeszcze odzywal.

    Pozdrawiam serdecznie i bardzo dziekuje ;)
  • #8 8371578
    silvanjk
    Poziom 12  
    Witam. Trafiłem tu ze względnie podobnym problemem.

    Jeśli jeszcze ktoś śledzi temat byłbym wdzięczny za pomoc ;)

    Mianowicie co do:
    fm=(m*fp)/N

    gdzie:
    fm - Czestotliwośc m-tej próbki
    fp - częstotliwość próbkowania
    m - numer próbki
    N- całkowita ilośc próbek

    Próbuję to u mnie wykonać (Delphi). Mam tablicę z danymi już po FFT.
    Teraz chcąc każdej próbce przyporządkować odpowiednią częstotliwość robię w ten sposób:
    
        f_przez_l:=f_prob/l_prob;
    
        for k3:= 0 to l_prob do
          begin
            chart2.Series[0].addxy(k3*f_przez_l, CH1mod[k3]);
    
          end;


    Gdzie wcześniej pobieram częstotliwość próbkowania z comboboxa (jest kilka do wyboru) - oraz liczbę próbek z pewnego labela, w którym owa liczba mi się wyświetla...
    Niestety - coś chyba jest nie tak, gdyż już przy FFT moja oś 'x' czyli częstotliwości jest zawsze od 0 do częstotliwości próbkowania. Jak mam 800Hz to do 800, jak 44100 to 44100, a jak 96000 to 96000.
    Przykładowo dla 44k1:
    FFT i skala dB ;)

    Czy to w ogóle jest dobrze? Sygnałem był sinus 50Hz.Niby jest ok względnie, gdyż przy przybliżeniu pierwszy pik (one są ledwie widoczne, czerwone po bokach) jest w okolicy 50Hz, ale zawsze jest ten drugi przy czestotliwości próbkowania minus czestotliwość sygnału (tu ok 44100 - 50 = 44050). Jak będzie 800 - to będzie to samo - pik przy 50Hz i przy 750.

    W ogóle liczba próbek nie ma znaczenia, tak jakby ten fragment kodu o dzieleniu jednej liczby przez drugą nie istniał.


    A druga sprawa to kwestia amplitudy. Radzicie tak wyskalować, aby zawierało się między 0 a 1. Ale skąd ja mogę wiedzieć, jakie ja maksymalne amplitudy będe jeszcze uzyskiwał / mierzył?
    W tym momencie korzystam z generatora sygnałów, który generuje amplitudę płynnie od 0 do 5V. To jak powinienem to wyskalować? Pod 5V, że to niby jest to '1'? A jak kiedyś będe musiał mierzyć 6V?

    Pozdrawiam, za pomoc podzielę się punktami, choć wiem, ze za wielu ich nie posiadam ;)
  • #9 8442430
    pburczyn
    Poziom 12  
    Tłumacząc najprościej w wyniku FFT otrzymujesz wektor, którego pierwsza połowa reprezentuje prążki o częstotliwościach od 0Hz do 1/2fp, a druga połowa tego wektora jest symetrycznym odbiciem pierwszej połowy...

    PB
REKLAMA