| Author |
Message
|
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#31
25 Sep 2006 06:54 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
CZesc
To ile tablic jest mi potrzebnych. Powiedzmy że mamay tablice spectrum po obliczeniach określoną spectrum[N] i jaki jeszcze będą potrzebne?
Dodano po 53 [minuty]:
Ale z tymi logarytmami to jest ne do mojego przypadku, czy tak. JEzeli mam zmienna spectrum typu uint16_t a ja zniej mam zrobić logarytm o wartości max 64. To co z tym.
Jeszcze chciałbym poprosić o szrszy opis opadania słupków widma (jesli moge). Chodzi to ze w przewaniu nastepuje uaktualnienie opadania a w pętli głównej z tablicy spectrum robisz aktualną watość prążka. i czy do każdego prążka mam inna warośc czasu?
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#32
25 Sep 2006 07:25 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Liczyłem logarytmy nie ze spektrum, a z wartości zespolonej (zauważ brak pierwiastkowania).
|
|
| Back to top |
|
 |
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#33
25 Sep 2006 09:24 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Ok. rozumiem.
tyle ze spectrum ma zakres od 0 do około 35000 a wynik ma być w zakresie 0 do 64. Czy to tak jest
|
|
| Back to top |
|
 |
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#34
01 Oct 2006 09:24 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Mam prośbę nie wiem jak sobie poradzić z tym logarytmowaniem czy może mi ktoś pomóc napisać to.
Druga rzecz która nie daje mi spokoju to obsługa słupków i pick-hold. Czy dla każdego słupka musi być osobna zmienna przechowująca czas opóźnienia, troche brakuje mi pamięci.
|
|
| Back to top |
|
 |
Prymulka Poziom 17

Joined: 10 Sep 2003 Posts: 382 Location: Bydgoszcz
|
#35
07 Oct 2006 17:41 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Witam
Wklepałem sobie program to Matlaba z książki Zielińskiego "CPS od teorii do zastosowań". Wygląda on tak:
%GENERACJA SYGNAŁU
N=8; %liczba próbek sygnału
x=0:N-1; %przykładowe wartości próbek
typBitReverse=1;
typFFT=1;
%PRZESTAWIENIE KOLEJNOŚCI PRÓBEK: wersja 1-wolna
if (typBitReverse==1)
MSB=log2(8);
for n=0:N-1;
ncopy=n;
nr=0;
for m=1:MSB
if(rem(n,2)==0)
n=n/2;
else
nr=nr+2^(MSB-m);
n=(n-1)/2;
end
end
y(nr+1)=x(ncopy+1);
end
x=y;
end
%WŁAŚCIWE FFT - wersja 1 - wolniejsza
if (typFFT==1)
for e=1:log2(N)
SM = 2^(e-1);
LB = N/(2^e);
LMB = 2^(e-1);
OMB = 2^e;
W = exp(-j*2*pi/2^e);
for b = 1 : LB
for m = 1 : LMB
g = (b-1)*OMB + m;
d = g + SM;
xgora = x(g);
xdol = x(d)*W^(m-1);
x(g) = xgora + xdol;
x(d) = xgora - xdol;
end
end
end
end
No i niby wszystko działa jak należy. Problem się zaczyna gdy wstawię większą liczbępróbek np. N = 128. W linii
xgora = x(g);
wyskakuje mio bład że g jest za duze (tzn wieksze niz maksymalny x czyli 127). No i jak sobie wszystko w głowie popodliczam to rzeczywiscie tak jest. Tylko nie mam pojecia co zrobic zeby tego bledu uniknac :/.
Czemu ten algorytm działa tylko dla N<=8?
|
|
| Back to top |
|
 |
Google

|
#
07 Oct 2006 17:41 |
|
|
|
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#36
07 Oct 2006 20:20 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Cześć, nie odpowiadałem ostatnio bom miał dość pijany koniec tygodnia. A to kolegę żona odeszła, a to prokuratorowi coś się przypomniało (trzeba było uczcić że niepotrzebnie), a to znowu mnie dopadły koszmary ;-).
Na otrzeźwienie poczytałem sobie „Cyberiadę”. Nie do końca podziałała, ale może dla tego że, w lodówce było jeszcze trochę płynnego jęczmienia?
Szkoda, że Lem’cio ostatnio uciekł w filosofię (i wspominki) z której tak pięknie szydził. Choć może w ten sposób zamknął jakoś swoje dzieło, by mniej nam było Go brak.
Ale wróćmy do dziesiątych pana Bell’a.
Maksimum w twoim widmie to X==65’614, trochę mnie to martwi, bo to więcej niż Atmelkowe MAXINT (czyli 2^(16-1) ale jest to może wynikiem sumowania oktawowego, no cóż, nasze ucho nie zna się na matematyce, ale zna się (ucho) na wynikach doświadczeń opisanych przez kolegę Darwina.
Zakładam, że prążek jest 16 bitową liczbą bez znaku („unsigned” co troszkę komplikuje zabawę).
I ja i Shag’u kombinowaliśmy z logarytmowaniem przy podstawie 2, proponowaliśmy podnoszenie do 4 potęgi albo do 2 (czyli brak pierwiastka z modułu, o czym pisałem) ale przecie to nie dodaje nowej informacji. A zróbmy sobie tabelkę (LUT z angielska) np. taką:
| Code: |
flash const unsigned int t[]=(
33622,29966,26707,23803,21214,18907,16851,15019,13386,11930,
10633, 9476, 8446, 7527, 6709, 5979, 5329, 4750, 4233, 3773,
3363, 2997, 2671, 2381, 2122, 1891, 1686, 1502, 1339, 1193,
1064, 948, 845, 753, 671, 598, 533, 475, 424, 378,
337, 300, 268, 239, 213, 190, 169, 151, 134, 120,
107, 95, 85, 76, 68, 60, 54, 48, 43, 38,
34, 30, 27, 24, 24); |
wtedy dla zadanego S gdy zawołamy:
| Code: |
j=0;
if (S<t[64]) j=65;
else while (t[j]>S)
j += 1; |
Wartość „1-j” odpowiada zaokrąglonej wartości 20*log(S/X) (X==35’614)
Tabelkę „t[]” stworzyłem tak:
| Code: |
p=69; //poprzednia wartość
for (i=X+10000; i>=23; j--) { // 23 bo 64 ;-)
db=round(20*log10(i/X));
if (db != p) {
t[-db]=i+1; //nie pamiętam czemu napisałem „+1”
p=db;
}
} |
Chyżej można przeglądać tabelkę „bisekcyjnie”, może warto?
Dygresja:
| Code: |
w C pisze się i kompiluje się efektywniej, lecz Pascal daje „magiczną” możliwość nadzorowania (nie lubię w sumie angielskiego słowa „controla”) zakresu zmiennych, indeksów itp, zauważyłem wiele „postuf” na forum (tym czy innym) wynikających tylko z tego, że np. indeks zagalopował[i] się zbyt daleko (czy blisko), albo że zmienna po dodaniu dodatniej wartości staje się ujemna. C daje nam <u>asercje</u> Fajna mechanika, lecz polega na „świadomości” programisty. W innym języku też to można zrobić, lecz C potrafi jakoś gładziej wygonić warunki z kompilowanego (na gotowo) kodu (w innych językach trzeba stosować warunkową kompilację). Polecam młodszym kolegom zaznajomienie się ze z tym sposobem.
Pytanko: jak zgrabniej przetłumaczyć słowo „assert”? „Asercja” jakoś drapie mnie w ucho, a litera „ł” nie może wystąpić w identyfkatorze. |
Druga dygresja:
| Code: |
| Język C, to już w zasadzie synonim zwięzłości (patrz np.:[url]http://www.ioccc.org/[/url]) a bywa że przegrywa pod tym względem ze staruszkiem FORTRANem. |
|
|
| Back to top |
|
 |
shg Poziom 22

Joined: 30 Sep 2003 Posts: 2302 Location: Trójkąt Bermudzki = Kędzierzyn-Koźle
|
#37
08 Oct 2006 02:04 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Powiem tak: diablo sprytnie, czyli szybko i dokładnie :]
Dla 64 punktów bedzie jak znalazł. Powinno działać szybciej niż operacje na 64 bitach.
Nie wiem, co na to kompilator, ale samą pętlę można zrealizować w 4 instrukcjach + skok:
| Code: |
pyntla:
LD Rx, Z+ ; zaladowanie dwoch kolejnych bajtow z tabeli
LD Ry, Z+
CP Rz, Rx ; porownanie z amplituda sygnalu
CPC Rw, Ry
BRCS pyntla |
Rx, Ry - do tych rejestrow ładowana jest wartość z tabeli.
Rz, Rw - w tych rejestrach przechowywana jest aktualna amplituda sygnału
x i z - bajt mniej znaczący, y i w - bajt bardziej znaczący.
Do rejestru Z przed rozpoczęciem wykonywania pętli ładowany jest wskaźnik na początek tablicy (w RAM), w sumie można by ją równie dobrze umieścić w pamięci programu, wtedy trzeba użyć LPM zamiast LD. odczyt z RAM jest szybszy, ale tablica zajmuje cenną pamięć.
Z warunkiem BRCS tak sobie strzeliłem tylko, może być inny (nigdy nie lubiałem skoków warunkowych :P), w każdym razie chodzi o skok gdy Rx:Ry będzie większe od Rz:Rw.
Oczywiście należy dopilnować żeby wartości w tablicy miały odpowiedni porządek bajtów (little-/big-endian) w razie potrzeby zamienić miejscami dwie pierwsze instrukcje.
Potem od tego co było w Z odejmujemy adres początku tablicy i to w zasadzie tyle.
Żeby mieć odrazu wysokość słupka można odwrócić wyszukiwanie (i kolejność elementów w tablicy) w ten sposób z wartości Z otrzymamy odrazu wysokość słupka.
A czy bisekcja będzie szybsza to nie wiem, przy większej tabeli na pewno, ale tu może okazać się, że overhead okaże się na tyle duży, że lepiej będzie użyć 'naiwnego' algorytmu przeszukiwania, czyli kolejno porównywać.
Dla każdego słupka wartość opóźnienia jest stała, ale każdy musi mieć swoją zmienną (a najlepiej w jednej tablicy to trzymać) w której jest licznik czasu opóźnienia po którym markery wartości szczytowych zaczynają opadać.
u mnie jest tak:
volatile uint16_t bars[N_BANDS]; /* wartości poszczególnych słupków w skali liniowej */
volatile uint8_t bands[N_BANDS]; /* wysokość słupków */
volatile uint8_t peaks[N_BANDS]; /* pozycja wartości szczytowej */
volatile uint8_t peak_delay[N_BANDS]; /* wyżej wymienione liczniki */
volatile uint8_t leds[N_BANDS]; /* to co będzie wyświetlane, każdy bit to jedna dioda, taka bitmapa w sumie */
Każdy słupek musi mieć osobny licznik czasu, bo inaczej zaczęły by opadać wszystkie w tym samym momencie i nie wiadomo w jakim, bo jakoś i tak by trzeba to zliczać, a jak jest jeden licznik to nie za bardzo się da (a właściwie to się da, tylko nie wiadomo, kiedy należało by go resetować).
Opadanie samych słupków nie wymaga osobnych zmiennych, potrzebna jest tylko tablica, która przechowuje ich wysokość i operuje się bezpośrednio na tej tablicy zmniejszając co pewnien ustalony czas każdy z jej elementów o 1 (o ile jest co zmniejszać, czyli tylko gdy dany element jest większy od 0).
To samo robimy z licznikami czasu dla każdego słupka - co jakiś czas zmniejszamy o 1 liczniki większe od zera.
I to samo z wartościami szczytowymi, ale dodatkowy warunek - zmniejszamy je tylko gdy odpowiadające im liczniki czasu mają wartość równą zero.
Liczniki czasu resetujemy (zapisujemy do nich żądaną wartość opóżnienia, nie zero) gdy wyliczona wysokość słupka jest większa od aktualnej pozycji markera wartości szczytowej.
Podobnie ze słupkami, jeżeli ma działać powolne opadanie, to elementy tablicy przechowującej wysokości słupków aktualizujemy wyłącznie jeżeli wyliczona wysokość jest większa od tej w tablicy, jak nie jest, to ją ignorujemy.
|
|
| Back to top |
|
 |
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#38
08 Oct 2006 11:23 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
cześć.
Czy mogę mieć do Ciebie prośbę?
Nie mam takiego doświadczenia w pisaniu prog. i powiem szczerze że teraz już nic z tego nie rozumiem. Co mam zrobić z tym logarytmem. jak teraz to ubrać w funkcję (najlepiej), która zwróci mi wynik właściwy z tablicy spectrum.
Chciałbym wrócic jeszcze do słupków i picków. Jak zamiast opadania pika srawić aby znikał. Codzi mi o to, ze widziałem w jednym sprzecie taki wskażnik, który też miał pick-hold, ale ten pik nie opadał tylko po pewnym czasie znikał i pojawiał sie nowy (po prostu pozbycie sie tylko opadania)
Bardzo prosze o pomoc, wiem że mozesz powiedzieć skoro nie do końca wiesz o co tu chodzi to sie nie zabieraj za to, ale z drugiej strony chciałbym bardzo dokończyć sobie to i zobaczyć efekt ciężkiej pracy oraz przy okazji sie duzo nauczyć (z waszą pomocą).
Sławek.
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#39
08 Oct 2006 12:06 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
| Code: |
int decybele(unsigned int S){
unsigned char j=0;
else while (t[j]>S)
j+=1;
return(1-j);
} |
|
|
| Back to top |
|
 |
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#40
08 Oct 2006 12:26 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Dzieki Xitami że odpowiedziałeś.
A możesz mi powiedziec cos o tej tablity t[] i jej powstaniu?
1. Skad liczba 69 oraz w petli for x+10000
2. czy ta funkca to jakby odpowiednik wzoru 20*log10(x/35614)
Poniewaz do logarytmu podstawiasz liczbe mniejsza od 1 to wyjdzxie ujemny a my operujemy na liczbach unsigned.
|
|
| Back to top |
|
 |
shg Poziom 22

Joined: 30 Sep 2003 Posts: 2302 Location: Trójkąt Bermudzki = Kędzierzyn-Koźle
|
#41
08 Oct 2006 12:31 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Ze znikaniem tak samo jak z opadaniem - też trzeba liczniki mieć i to w takiej samej ilości. Różnice:
Nie zmniejszamy co określony czas elementów tablicy przechowujących wartości szczytowe. Zmniejszamy tylko liczniki czasu.
Podczas wyświetlania rysujemy tylko te punkty, których liczniki czasu są większe od zera.
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#42
10 Oct 2006 09:32 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Przejrzałem i uładziłem.
| Code: |
flash const unsigned int t[64]={ // 0 .. –64 dB, tym sposobem można do –77dB
33622,29966,26707,23803,21214,18907,16851,15019,
13386,11930,10633, 9476, 8446, 7527, 6709, 5979,
5329, 4750, 4233, 3773, 3363, 2997, 2671, 2381,
2122, 1891, 1686, 1502, 1339, 1193, 1064, 948,
845, 753, 671, 598, 533, 475, 424, 378,
337, 300, 268, 239, 213, 190, 169, 151,
134, 120, 107, 95, 85, 76, 68, 60,
54, 48, 43, 38, 34, 30, 27, 24};
signed char decybel(unsigned int s) { // 20*log10(s/35614)
char j=0;
if (s < t[63]) j=64;
else while (s < t[ j])
j++;
return(-j); //jeżeli przeszkadzają ujemne zwróć 64-j
} |
tabelka powstała tak:
| Code: |
p:=0;
for i:=x downto 23 do begin { 23 odpowiada –64 dB }
db:=round(20*log10(i/35614));
if db <> p then begin
t[-1-db]:=i+1;
p:=db
end
end; |
|
|
| Back to top |
|
 |
slawek55 Poziom 18

Joined: 20 Jan 2003 Posts: 588 Location: Szczecin
|
#43
10 Oct 2006 11:24 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Dzięki.
T aTwoja tabelka i funkcja decybel jest odwrotnie proporcjonalna do wartości wejsciowej liczbie S na wejsciu dużej odpowiada mała na wyjsciu funkcji.
Jak robić tak aby liczbie np z końca zakresu (35614) odpowiadała liczba na końcu skali (64), bo narazie jest odwrotnie?
A i skąd pomysł n takie wyliczenia z takelką - świetny!
P.S.
A jak powstała liczba 23 odpowiadająca -64db. U mnie ta liczba 64 to poprostu ilośc (rozdzielczośc) słupków.
|
|
| Back to top |
|
 |
Xitami Poziom 21

Joined: 10 Aug 2004 Posts: 1126 Location: Gliwice
|
#44
10 Oct 2006 15:02 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Decybel to stosunek. Możemy odnosić się do maksimum, wtedy 0 mam dla wartości maksymalnej, a minus ileś tam dla minimalnej.
W funkcji decybel popraw na "return(64-j)" i będzie klawo. 64 dla max i 0 dla maleńkich.
Napisałem, że sposób dobry do -77 dB, ale trzeba pamiętać jeszcze o czymś.
Jeżeli przetwornik ma powiedzmy 10 bitów wtedy dynamika to tylko około 60 dB (bitowość*6).
Wszystko co mniejsze to szum kwantyzacji, błędy zaokrągleń i promieniowanie reliktowe.
20*log(23/35614) == -64 dB
No to mamy 64 ziarenka w słupku co 1 dB.
A pomysł z tabelką? Nie jest mój, prawie zawsze gdy chcemy szybko liczyć cos złożonego,
można użyć tabelki z przygotowanymi wcześniej obliczeniami, prawie bo tabelka może być
zbyt wielka, nie dla RAM ale dla CACHE (co nie grozi AVRom) i czasem na PC np. w FFT warto
liczyć sinusa i cosinusa
|
|
| Back to top |
|
 |
Google

|
#
10 Oct 2006 15:02 |
|
|
|
|
|
| Back to top |
|
 |
r06ert Poziom 20

Joined: 03 Dec 2004 Posts: 940 Location: woj. wielkopolskie
|
#45
04 Jul 2007 17:48 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
Witam! Sam postanowiłem się pobawić DFT ...i w końcu trafiłem tutaj ;)
Napisałem taki fragment kodu:
| Code: |
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "ffft.h"
void fft_input (const int16_t *, complex_t *);
void fft_execute (complex_t *);
void fft_output (complex_t *, uint16_t *);
//int16_t fmuls_f (int16_t, int16_t);
int16_t capture[FFT_N];
complex_t bfly_buff[FFT_N];
uint16_t spectrum[FFT_N/2];
int maina(){
while(1){
//pobieranie próbek
fft_input(capture,bfly_buff);
fft_execute(bfly_buff);
fft_outpu(bfly_buff,spectrum);
//wizualizacja wyniku
}
}
|
jednak wyskakuje błędąd kompilacji:
ffft.h:15: - error: multiple storage classes in declaration of `complex_t'
już nie mam pomysły co to może byc... Czy któryś z szanownych kolegów którym udało się użyć biblioteki ffft.h pomógłby mi? z góry dzięki, pozdrawiam!
|
|
| Back to top |
|
 |
Google

|
#
04 Jul 2007 17:48 |
|
|
|
|
|
| Back to top |
|
 |
long_os Poziom 5

Joined: 28 Dec 2009 Posts: 11
|
#46
23 Feb 2010 15:22 Re: Potrzebna pomoc w Dyskretnej Transformacie Fouriera |
|
|
|
A mi podczas kompilacji Avr-gcc wypluł coś takiego:
| Code: |
> "make.exe" all
-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiling C: main.c
avr-gcc -c -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./main.lst -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o main.o
In file included from main.c:33:
ffft.h:12: error: multiple storage classes in declaration specifiers
ffft.h:21: error: expected declaration specifiers or '...' before 'complex_t'
ffft.h:24: error: expected ')' before '*' token
ffft.h:25: error: expected ')' before '*' token
main.c:37: error: redefinition of 'struct _tag_complex_t'
main.c:40: error: 'complex_t' redeclared as different kind of symbol
ffft.h:15: error: previous declaration of 'complex_t' was here
main.c:42: error: conflicting types for 'fft_input'
ffft.h:21: error: previous declaration of 'fft_input' was here
make.exe: *** [main.o] Error 1
> Process Exit Code: 2
> Time Taken: 00:02 |
Kod bez żadnych zmian i przeróbek :/ Co jest przyczyną ?
|
|
| Back to top |
|
 |